我对如何最好地处理这种情况感到困惑。我不想等待异步调用的响应。具体来说我有:
public async Task<IApiData> FetchQueuedApiAsync(TimeSpan receiveTimeout)
{
var message = await Task.Factory.FromAsync<Message>(
ReadQueue.BeginReceive(receiveTimeout), ReadQueue.EndReceive);
return message.Body as IApiData;
}
这按预期工作。但是,如果超时到期,则不得调用 ReadQueue.EndReceive,否则会引发异常。显然 FromAsync 不知道这一点并盲目地调用它 - 引发异常。超时时不调用 EndReceive 的要求是由 MSMQ 实现的,超出了我的控制范围。
当消息准备好或发生超时时,队列会公开一个事件。您通常会在此处检查消息是否存在,然后根据文档调用 EndReceive。标准监听器....
ReadQueue.ReceiveCompleted += ReadQueue_ReceiveCompleted;
我的问题是,我不明白如何做到这一点,并且仍然将其视为可等待的(即我希望能够像现在一样等待,但通过委托处理它)。那有意义吗?
通常,当您想要将某些非基于任务的异步模型转换为基于任务的异步模型时,如果还没有Task
方法为您进行转换,您使用TaskCompletionSource
“手动”处理每种情况:
public Task<IApiData> FetchQueuedApiAsync(TimeSpan receiveTimeout)
{
var tcs = new TaskCompletionSource<IApiData>();
ReadQueue.BeginReceive(receiveTimeout);
ReadQueue.ReceiveCompleted += (sender, args) =>
{
if (timedOut)
tcs.TrySetCanceled();
else if (threwException)
tcs.TrySetException(exception);
else
tcs.TrySetResult(ReadQueue.EndReceive() as IApiData);
};
return tcs.Task;
}
您需要根据未显示的类型的具体情况进行调整,但这是总体思路。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)