我正在开发一个库,该库在 UI 线程上执行一些惰性空闲后台工作(由于使用旧版 COM,因此必须这样做)。该任务可以由使用应用程序通过取消 token 取消,也可以由于用户操作而显式取消(通过 IUserFeedback.Continue
)。我正在尝试按照 MSDN pattern 来取消任务。
我的问题是,我是否应该区分用户取消(并返回 false
)和调用应用程序取消(抛出),就像 IdleWorker1
那样。或者我应该平等对待这两种情况并直接抛出,就像 IdleWorker2
一样?
我对界面设计者没有任何严格的要求(任务本质上是永无止境的,所以他们只关心到目前为止实际完成了多少工作,并且他们通过 IUserFeedback.Continue
接收进度) .
简而言之,IdleWorker1:
interface IUserFeedback
{
bool Continue(int n);
}
class IdleWorker1
{
public async Task<bool> DoIdleWorkAsync(CancellationToken ct, int timeSlice, IUserFeedback feedback)
{
bool more = true;
int n = 0;
while (more)
{
ct.ThrowIfCancellationRequested();
more = feedback.Continue(++n);
await Task.Delay(timeSlice);
}
return more;
}
}
IdleWorker2:
class IdleWorker2
{
public async Task DoIdleWorkAsync(CancellationToken ct, int timeSlice, IUserFeedback feedback)
{
int n = 0;
for (;;)
{
ct.ThrowIfCancellationRequested();
if (!feedback.Continue(++n))
throw new TaskCanceledException();
await Task.Delay(timeSlice);
}
}
}
最佳答案
我认为,如果您不需要区分两种类型的取消,则取消的方法甚至不应该知道是谁取消了它。
为此,您需要一个 CancellationTokenSource
供应用取消,另一个供用户取消。然后,您可以使用 CreateLinkedSource()
将它们合并为一个。并将其 token 传递给该方法。
关于c# - 异步任务取消最佳实践 : user versus program,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18886803/