【发布时间】:2015-12-02 07:37:02
【问题描述】:
我最近使用我在很多地方看到的取消模式重新实现了一大堆异步 WCF 服务方法 - 您在已启动任务和 Task.Delay 上等待 Task.WhenAny。当然,现有任务是不可取消的,但希望在以后的版本中解决。
在我的例子中,Task.Delay 的默认持续时间由服务设置控制。在绝大多数情况下,结果是希望的任务在必要的时间内完成。设置通常很慷慨。
我见过的大多数(但不是全部)示例都懒得取消Task.Delay。这么便宜就不用担心了吗?我知道取消会引发异常。如果我取消延迟,我应该处理异常吗?
这是我创建的所有服务方法都通过它调用的方法:
private async Task<T> GetOrTimeout<T>( Task<T> task, [CallerMemberName] string caller = "" )
{
using ( var cts = new CancellationTokenSource( ) )
{
try
{
var timeout = GetDelay( cts.Token );
var first = await Task.WhenAny( task, timeout );
if ( first == timeout ) throw new TimeoutException( Properties.Resources.TimeoutOccurredInService.Fmt( caller ) );
cts.Cancel( ); //--> haven't been doing this. Should I?
return await task;
}
catch ( Exception ex )
{
throw LoggedFaultException( ex, caller );
}
}
}
...产生延迟的方法如下所示:
private Task GetDelay( CancellationToken token )
{
return Task
.Delay( Properties.Settings.Default.ServiceMethodTimeout, token )
.ContinueWith( _ => { }, TaskContinuationOptions.ExecuteSynchronously );
}
如果我不取消延迟,我持有资源的时间是否超过了必要的时间?特别是,我担心 WCF 启动以调用服务方法的实例。我担心他们会削减服务配置的并发参数。超时设置非常粗糙。不取消似乎很浪费,但这对我来说都是全新的东西。
由于取消涉及异常,并且由于我接受过不使用异常来传达状态的培训,这感觉就像我将自己描绘成一些我不完全理解的可怕的反模式。也许Task.Delay 对我来说不是正确的选择。 感觉好像我把它弄得比我应该做的更复杂。任何关于这种情况的线索将不胜感激。
【问题讨论】:
标签: c# .net wcf async-await task-parallel-library