And*_*age 3 c# asynchronous msmq
我很困惑如何最好地处理这种情况.我不想等待异步调用的响应.具体来说,我有:
public async Task<IApiData> FetchQueuedApiAsync(TimeSpan receiveTimeout)
{
var message = await Task.Factory.FromAsync<Message>(
ReadQueue.BeginReceive(receiveTimeout), ReadQueue.EndReceive);
return message.Body as IApiData;
}
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是,如果超时到期,则不得调用ReadQueue.EndReceive,否则将引发异常.显然,FromAsync并不知道这一点并盲目地调用它 - 解雇异常.不要在超时时调用EndReceive的要求由MSMQ实现,超出了我的控制范围.
当消息准备就绪或发生超时时,队列会公开事件.这是您通常检查消息是否存在的地方,然后根据文档调用EndReceive.标准听众......
ReadQueue.ReceiveCompleted += ReadQueue_ReceiveCompleted;
Run Code Online (Sandbox Code Playgroud)
我的问题是,我不明白如何做到这一点,仍然有这样的等待(即我希望能够等待我现在,但通过委托处理它).那有意义吗?
通常,当您想要将一些基于任务的异步模型转换为基于任务的异步模型时,如果还没有一种Task方法可以为您进行转换,则使用a 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;
}
Run Code Online (Sandbox Code Playgroud)
您需要根据未显示的类型的具体情况进行调整,但这是一般性的想法.
| 归档时间: |
|
| 查看次数: |
4192 次 |
| 最近记录: |