BILL
BILL

Reputation: 4869

Why don't execute task in ContinueWith?

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

Answers (2)

Ribtoks
Ribtoks

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

Sergei B.
Sergei B.

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

Related Questions