使用任务有条件延续 [英] Using Tasks with conditional continuations

查看:159
本文介绍了使用任务有条件延续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何使用任务有条件延续有点糊涂了。

I'm a little confused about how to use Tasks with conditional Continuations.

如果我有一个任务,然后我想继续进行任务处理成功和错误,然后等待这些完成。

If I have a task, and then I want to continue with a tasks that handle success and error, and then wait on those to complete.

void FunctionThrows() {throw new Exception("faulted");}

static void MyTest()
{

    var taskThrows = Task.Factory.StartNew(() => FunctionThrows());

    var onSuccess = taskThrows.ContinueWith(
                          prev => Console.WriteLine("success"), 
                          TaskContinuationOptions.OnlyOnRanToCompleted);

    var onError = taskThrows.ContinueWith(
                          prev => Console.WriteLine(prev.Exception),
                          TaskContinuationOptions.OnlyOnFaulted);

    //so far, so good



    //this throws because onSuccess was cancelled before it was started
    Task.WaitAll(onSuccess, onError);
}

这是在做任务的成功/失败分支的preferred方式?此外,我怎么加入所有这些任务,假设我已经创建延续了很长的线,各有自己的错误处理。

Is this the preferred way of doing task success/failure branching? Also, how am I supposed to join all these tasks, suppose I've created a long line of continuations, each having their own error handling.

  //for example
  var task1 = Task.Factory.StartNew(() => ...)
  var task1Error = task1.ContinueWith(  //on faulted
  var task2  = task1.ContinueWith(      //on success
  var task2Error = task2.ContinueWith(  //on faulted
  var task3 = task2.ContinueWith(       //on success
  //etc

调用为WaitAll 这些不约而同地抛出,因为有些延续会由于被取消的 TaskContinuationOptions ,和调用等待上已取消的任务抛出。 如何加入这些没有得到任务已取消例外?

Calling WaitAll on these invariably throws, because some of the continuations will be cancelled due to the TaskContinuationOptions, and calling Wait on a cancelled task throws. How do I join these without getting the "A task was cancelled" exception"?

推荐答案

我觉得你的主要问题是,你是说这两个任务,以等待与您的来电

I think your main problem is that you're telling those two tasks to "Wait" with your call to

Task.WaitAll(onSuccess, onError);

的onSuccess 的onError 的延续是自动设置为你和将要执行的 的其先行任务完成后。

The onSuccess and onError continuations are automatically setup for you and will be executed after their antecedent task completes.

如果您只需更换你的 Task.WaitAll(...) taskThrows.Start(); 我相信你会得到所需的输出。

If you simply replace your Task.WaitAll(...) with taskThrows.Start(); I believe you will get the desired output.

下面是一个有点一个例子,我放在一起的:

Here is a bit of an example I put together:

class Program
{
    static int DivideBy(int divisor) 
    { 
      Thread.Sleep(2000);
      return 10 / divisor; 
    }

    static void Main(string[] args)
    {
        const int value = 0;

        var exceptionTask = new Task<int>(() => DivideBy(value));

        exceptionTask.ContinueWith(result => Console.WriteLine("Faulted ..."), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent);
        exceptionTask.ContinueWith(result => Console.WriteLine("Success ..."), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);

        exceptionTask.Start();

        try
        {
            exceptionTask.Wait();
        }
        catch (AggregateException ex)
        {
            Console.WriteLine("Exception: {0}", ex.InnerException.Message);
        }

        Console.WriteLine("Press <Enter> to continue ...");
        Console.ReadLine();
    }
}

这篇关于使用任务有条件延续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆