1

我正在处理的网站上有一个登录页面,并且在调用该页面的操作时,会进行一些异步 Web 调用以缓存结果以供以后使用。不过,我想做的是等待调用完成,然后再进行下一个操作。基本上我有:

GetParticipantInfo(planID, partID );

SetCurrentInvestments(partID, planID);

GetLoanFunds(planID, partID);

并且每个都像这样拆分:

public void GetParticipantInfo(string planNumber, string participantID)
    {
        IAsyncResult _IAsyncResult;
        List<string> parameter = new List<string>();
        parameter.Add(planNumber);
        parameter.Add(participantID);
        GetParticipantInfo_A _GetParticipantInfo_A = new GetParticipantInfo_A(GetParticipantInfoAsync);
        _IAsyncResult = _GetParticipantInfo_A.BeginInvoke(participantID, planNumber, serviceContext, GetParticipantInfoAsyncCallBack, parameter);

    }

    public ParticipantDataModel GetParticipantInfoAsync(string planNumber, string partId, ServiceContext esfSC)
    {

        ParticipantDataModel pdm = new ParticipantDataModel();
        return pdm;

    }

    private void GetParticipantInfoAsyncCallBack(IAsyncResult ar)
    {
        try
        {
            AsyncResult result;              
            result = (AsyncResult)ar;
            string planID = ((List<string>)ar.AsyncState)[0];
            GetParticipantInfo_A caller = (GetParticipantInfo_A)result.AsyncDelegate;
            ParticipantDataModel pdm = caller.EndInvoke(ar);
            _cacheManager.SetCache(planID, CacheKeyName.GetPartInfo.ToString(), pdm);
        }
        catch (Exception ex)
        { }
    }

所以问题是,如何设置 UI 线程以等待调用完成,然后再进行其他操作?

回应乔:

好的,所以假设他们都返回 asyncresult,我可以做类似的事情:

List<IAsyncResult> results;
//After each call
result = OneOfTheAsyncCalls();
results.Add(result);

foreach(IAsyncResult result in results)
{
     result.AsyncWaitHandle.WaitOne();
}

还是顺序很重要?

4

3 回答 3

3

你能在调用者和异步回调之间使用 AutoResetEvent 吗?

于 2012-05-21T14:00:31.643 回答
1

您可以使用IAsyncResult.AsyncWaitHandle等待异步操作完成。

您的示例代码(例如 GetParticipantInfo)丢弃了IAsyncResult. 相反,将其返回给调用者。

查看我对原始问题的编辑

是的,您的编辑看起来会起作用(或者您可以使用WaitAll而不是循环播放WaitOne)。

于 2012-05-21T14:00:13.097 回答
1

重构您的方法,以便他们使用该Task.FromAsync方法。例如,GetParticipantInfo看起来像这样。我基本上将所有内容整合到这个方法中。

public Task<ParticipantDataModel> GetParticipantInfo(string planNumber, string participantID)
{
  var instance = new GetParticipantInfo_A(
    (planNumber, partID, esfSC) =>
    {
      return new ParticipantDataModel();
    }
  );
  var main = Task<ParticipantDataModel>.Factory.FromAsync(
    instance.BeginInvoke, 
    instance.EndInvoke, 
    participantID, 
    planNumber, 
    serviceContext,
    null);
  var continuation = main.ContinueWith(
    task =>
    {
      lock (_cacheManager)
      {
        _cacheManager.SetCache(planNumber, CacheKeyName.GetPartInfo.ToString(), task.Result);
      }
    });
  return continuation;
}

然后您的页面请求代码将如下所示。我曾经Task.WaitAll阻止页面请求线程,直到每个单独的任务完成。

private void YourButton_Click(object sender, EventArgs args)
{
  var t1 = GetParticipantInfo(partID, plantID);
  var t2 = SetCurrentInvestments(partID, planID);
  var t3 = GetLoanFunds(planID, partID);
  Task.WaitAll(t1, t2, t3);
}
于 2012-05-21T14:52:31.163 回答