1

作業中のWebサイトにランディングページがあり、そのページのアクションが呼び出されると、後で結果をキャッシュするために、いくつかの非同期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ようになります。私は基本的にすべてをこの1つの方法に統合しました。

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 に答える