异步调用 - 如何在 UI 线程上等待它们
本文关键字:线程 等待 UI 调用 异步 | 更新日期: 2023-09-27 18:34:54
我在我正在处理的网站上有一个登录页面,并且在调用该页面的操作时,会进行一些异步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 线程以等待调用完成,然后再继续其他操作?
回应乔:
好的,所以假设它们都返回异步结果,我可以做这样的事情吗:
List<IAsyncResult> results;
//After each call
result = OneOfTheAsyncCalls();
results.Add(result);
foreach(IAsyncResult result in results)
{
result.AsyncWaitHandle.WaitOne();
}
还是顺序很重要?
您是否能够在调用方和异步回调之间使用 AutoResetEvent?
您可以使用
IAsyncResult.AsyncWaitHandle
等待异步操作完成。
您的示例代码(例如 GetParticipantInfo(会丢弃IAsyncResult
。 相反,请将其返回给调用方。
查看我对原始问题的编辑
是的,您的编辑看起来可以工作(或者您可以使用WaitAll
而不是循环WaitOne
(。
重构方法,使其使用 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);
}