c# - 异步任务取消最佳实践 : user versus program

标签 c# .net task-parallel-library async-await

我正在开发一个库,该库在 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/

相关文章:

c# - 如何检测与背景颜色相同的物体

c# - 基类实现接口(interface)

c# - 系统.IO.FileNotFoundException : Could not load file or assembly

C#变量新鲜度

.net - TPL数据流和Akka.net有什么区别?

c# - 我应该使用什么形式的任务控制来使用 SignalR 处理 MVC 中长时间运行的进程

c# - ZedGraph 饼图上的自定义标签

c# - 打开多个文件(OpenFileDialog,C#)

c# - 是否有一个 API 可以设置双击的第一次和第二次点击之间可能发生的最小毫秒数?

c# - 转换表以在 C# 中的 Linq 中添加更多列