4

オブジェクトを返す非同期メソッドがあります

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を更新したいのですが、メソッドGetUserResponseApiが値を返さないため、UIが更新されない可能性があります。

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

でContinueWithの問題を解決する方法はGetUserResponseApi

更新:GetUserResponseApiブロックContinueWithが実行されないため 、メソッドに問題があると思います。

4

2 に答える 2

3

Application.Current.DispatcherUIオブジェクトにアクセスするたびに、UIスレッドに呼び出しをディスパッチするために使用します。

Application.Current.Dispatcher.Invoke(() => {
try
{
richTextBox1.Text += string.Format("ID:{0} online:{1}", user.uid, user.online);
}
catch
{
   //handle
}
), DispatcherPriority.Background);
于 2012-06-22T12:23:11.727 に答える
2

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());
于 2012-06-22T12:25:56.667 に答える