Reputation: 4869
I have async methods that returns an objects
public static IEnumerable<Users.User> GetUsers(IEnumerable<string> uids, Field fields)
{
Task<ResponseApi<Users.User>>[] tasks;
tasks = uids.Select(uid =>
{
var parameters = new NameValueCollection
{
{"uids", uid},
{"fields", FieldsUtils.ConvertFieldsToString(fields)}
};
return GetUserResponseApi(parameters);
}).ToArray();
Task.WaitAll(tasks);
foreach(Task<ResponseApi<Users.User>> task in tasks)
{
if(task.Result.Response != null)
{
yield return task.Result.Response;
}
}
}
And I want to update UI in other method,UI maybe don't update because method GetUserResponseApi don't return any value.
public static Task<ResponseApi<Users.User>> GetUserResponseApi(NameValueCollection parameters)
{
return CallMethodApi("users.get", parameters, CallType.HTTPS)
.ContinueWith(
r =>
{
//don't execute
var responseApi = new ResponseApi<Users.User>();
responseApi.Response = JsonConvert.DeserializeObject<Users.User>(r.Result["response"][0].ToString());
return responseApi;
});
}
private void BtnGetUsersClick(object sender, EventArgs e)
{
var random = new Random();
int max = 175028595;
var uids = new List<string>();
for(int i = 1; i <= 20; i++)
{
uids.Add((random.Next(max) + 1).ToString());
}
Task.Factory.StartNew(() =>
{
var users = VkontakteApi.GetUsers(uids, Field.Online);
foreach(var user in users)
{
richTextBox1.Text += string.Format("ID:{0} online:{1}", user.uid,
user.online);
}
}, CancellationToken.None, TaskCreationOptions.None, _uiContext);
}
How to resolve problem with ContinueWith in GetUserResponseApi
?
UPDATE:
I think that problem in method GetUserResponseApi
because block ContinueWith doesn't execute.
Upvotes: 4
Views: 825
Reputation: 6922
Try using TaskScheduler.FromCurrentSynchronizationContext()
method:
Task.Factory.StartNew(() =>
{
var users = VkontakteApi.GetUsers(uids, Field.Online);
foreach(var user in users)
{
richTextBox1.Text += string.Format("ID:{0} online:{1}", user.uid,
user.online);
}
}, CancellationToken.None,
TaskScheduler.FromCurrentSynchronizationContext());
Upvotes: 2
Reputation: 3227
Use Application.Current.Dispatcher
to dispatch calls to UI thread whenever you access UI objects.
Application.Current.Dispatcher.Invoke(() => {
try
{
richTextBox1.Text += string.Format("ID:{0} online:{1}", user.uid, user.online);
}
catch
{
//handle
}
), DispatcherPriority.Background);
Upvotes: 3