操作正在运行时异步取消

时间:2014-01-15 10:20:06

标签: c# .net async-await cancellationtokensource

我正在开始对.net中的异步编程进行一些测试,现在我仍然坚持尝试使用cancellationToken取消长时间操作。

所以我有以下代码:

CancellationTokenSource cancelationToken = new CancellationTokenSource();

我的按钮开始操作

    private void button2_Click(object sender, EventArgs e)
    {
        cancelationToken.Cancel(true);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        StartOperation(cancelationToken.Token);
    }

最后我的行动

    private async void StartOperation(CancellationToken cancelToken)
    {
        await GetItensFromDatabase2(cancelToken);
    }

    public static Task<int> GetItensFromDatabase(CancellationToken cancelToken)
    {
        //cancelToken.Register( () => Console.WriteLine("Canceled") );
        return Task.Factory.StartNew<int>(() =>
        {
            int result = 0;

            cancelToken.ThrowIfCancellationRequested();

            result = MyLongOperation();  // Simulates my operation -> I want to cancel while this operation is still running

            return result;

        }, cancelToken);
    }

那么,如何取消MyLongOperation()方法呢?有可能吗?

2 个答案:

答案 0 :(得分:5)

不可能在任何一点取消,CancellationToken的目的是允许用户取消操作,当长时间运行的操作期望...

while(!finished)
{
     cancelToken.ThrowIfCancellationRequested();
     //Some not cancelable operations
}

这是更常用的可取消方法

private static void LongRunning(CancellationToken cancelToken)
{
    while (true)
    {
        if(cancelToken.IsCancellationRequested)
        {
            return;
        }
        //Not canceled, continue to work
    }
}

这个想法是,该用户请求取消,但只有执行者决定何时停止他的工作。通常执行人在达到某些“安全点”后会取消

Abort在不提出意见的情况下进行长期运行并不是很好的经验,很多帖子都是关于此的。

答案 1 :(得分:1)

对于初学者来说,如果你已经完成了“cancelToken.ThrowIfCancellationRequested”的逻辑然后你取消了,你会遇到一个问题。 “MyLongOperation”将如何知道您已取消该任务? :)

取消长时间运行的任务通常会将CancellationToken作为参数,因此代码看起来像:

// Check if cancelled
// do work part 1
// Check if cancelled
// do work part 2

可取消操作的粒度取决于开发人员。