我最近重新实现了一批使用异步WCF服务方法,采用了我在许多地方看到的取消模式——在启动任务和Task.Delay上等待
在我的情况下,默认的
我看到的大部分(但不是全部)示例都没有费心取消
以下是我制作的所有服务方法都在调用的方法:
而创建延迟的方法看起来会像这样:
如果我不取消延迟,那么我是否会占用资源比必要的时间更长?特别是,我担心WCF生成来调用服务方法的实例。我担心它们会削弱配置为服务的并发参数。超时设置很粗糙。不取消似乎是一种浪费,但这对我来说都是新东西。
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
不是适合我的选择。感觉上好像我把它弄得比应该的更复杂了。非常感谢您能为我解惑。
Task.Delay
的令牌取消后会释放计时器。我以为它的行为方式与常规任务检查取消相同,但事实并非如此。 - Alexei Levenkov