对Task.Run

时间:2016-04-04 01:09:15

标签: c# task cancellationtokensource

我有一些代码使用带有取消令牌的Task.Run

这是我的代码:

public class TaskObject
{
    CancellationTokenSource _source = new CancellationTokenSource();
    public async Task TaskAction()
    {
        var task = Task.Run(async delegate
        {
            await TaskRun();
        }, _source.Token);

        //TaskCancel();

        try
        {
            task.Wait();
        }
        catch (Exception ex)
        {

        }
    }
    public async Task TaskRun()
    {
        if (_source.IsCancellationRequested)
        {
            _source.Token.ThrowIfCancellationRequested();
        }

        SpeechSynthesizer _speechSynthesizer = new SpeechSynthesizer();
        _speechSynthesizer.SpeakAsync("This is a test prompt");
    }
    public void TaskCancel()
    {
        _source.Cancel();
    }
}

如果我调用TaskCancel()中的TaskAction(),则会捕获任务取消的异常。

如果我从对象外部调用TaskCancel(),则不会捕获已取消的异常。

以下是一些代码,用于演示未捕获已取消异常的位置:

taskObject = new TaskObject();
await taskObject.TaskAction();
taskObject.TaskCancel();

如何从对象外部调用TaskCancel()以便捕获已取消的异常?

1 个答案:

答案 0 :(得分:4)

取消需要合作。 $HOME无法了解预定代理可能产生的副作用,因此\可以检查您的$并抛出OCE的唯一逻辑安全点(不会将您的应用程序保留在在异步操作开始之前

麻烦的是,您的用户代码大部分时间都在等待sudo -s -H <<EOF echo "Called by: $USER; root's home dir: \$HOME" EOF ,其中没有超载接受Task.Run

Task.Run确实有一个CancellationToken方法,您可以将其插入:

SpeechSynthesizer.SpeakAsync

我无法告诉你这是否会产生异常,表明操作已被取消 - 你需要亲自试试。