为什么不在ContinueWith中执行任务?

时间:2012-06-22 12:20:07

标签: c# winforms task-parallel-library task

我有返回对象的异步方法

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;
        }
    }
}

我想用其他方法更新UI,UI可能不会更新,因为方法GetUserResponseApi不返回任何值。

 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);
    }

如何解决GetUserResponseApi中的ContinueWith问题?

更新 我认为方法GetUserResponseApi中的问题因为块ContinueWith没有执行。

2 个答案:

答案 0 :(得分:3)

每当您访问UI对象时,都使用Application.Current.Dispatcher来调度UI线程。

Application.Current.Dispatcher.Invoke(() => {
try
{
richTextBox1.Text += string.Format("ID:{0} online:{1}", user.uid, user.online);
}
catch
{
   //handle
}
), DispatcherPriority.Background);

答案 1 :(得分:2)

尝试使用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());