异步任务的顺序处理 [英] Sequential processing of asynchronous tasks

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

问题描述

假设以下同步code:

Assume the following synchronous code:

try
{
    Foo();
    Bar();
    Fubar();
    Console.WriteLine("All done");
}
catch(Exception e) // For illustration purposes only. Catch specific exceptions!
{
    Console.WriteLine(e);
}

现在假设所有这些方法都有一个异步对口,我不得不使用那些由于某种原因,所以简单地把整个事情在一个新的任务是不是一种选择。
我将如何实现相同的行为?
我的意思与同是:

Now assume all these methods have an Async counterpart and I have to use those for some reason, so simply wrapping the whole thing in a new task is not an option.
How would I achieve the same behavior?
What I mean with "same" is:

  1. 执行一个异常处理程序,如果被抛出。
  2. 停止执行下面的方法,如果有异常被抛出。

我唯一能拿出来说的可怕

The only thing I was able to come up with is horrible:

var fooTask = FooAsync();
fooTask.ContinueWith(t => HandleError(t.Exception),
                     TaskContinuationOptions.OnlyOnFaulted);
fooTask.ContinueWith(
    t =>
    {
        var barTask = BarAsync();
        barTask.ContinueWith(t => HandleError(t.Exception),
                             TaskContinuationOptions.OnlyOnFaulted);
        barTask.ContinueWith(
            t =>
            {
                var fubarTask = FubarAsync();
                fubarTask.ContinueWith(t => HandleError(t.Exception),
                                       TaskContinuationOptions.OnlyOnFaulted);
                fubarTask.ContinueWith(
                    t => Console.WriteLine("All done"),
                    TaskContinuationOptions.OnlyOnRanToCompletion);
            }, 
            TaskContinuationOptions.OnlyOnRanToCompletion);
    }, 
    TaskContinuationOptions.OnlyOnRanToCompletion);

请注意:

  • 我需要一个解决方案,使用.NET 4的作品,所以异步/计谋是出了问题。但是,如果将与工作异步/计谋随意展示如何。
  • 在我不需要使用第三方物流。如果是与第三方物流是不可能的另一种方法是好的,可能与无功扩展?
  • I need a solution that works with .NET 4, so async/await is out of the question. However, if it would work with async/await feel free to show how.
  • I don't need to use the TPL. If it is impossible with the TPL another approach would be OK, maybe with Reactive Extensions?

推荐答案

下面是如何将与工作异步

try
{
    await FooAsync();
    await BarAsync();
    await FubarAsync();
    Console.WriteLine("All done");
}
catch(Exception e) // For illustration purposes only. Catch specific exceptions!
{
    Console.WriteLine(e);
}

如果您安装了($ P $租赁前) Microsoft.Bcl.Async包

This would work on .NET 4.0 if you installed the (prerelease) Microsoft.Bcl.Async package.

既然你被困在VS2010,您可以使用斯蒂芬变体Toub的然后

Since you're stuck on VS2010, you can use a variant of Stephen Toub's Then:

public static Task Then(this Task first, Func<Task> next)
{
  var tcs = new TaskCompletionSource<object>();
  first.ContinueWith(_ =>
  {
    if (first.IsFaulted) tcs.TrySetException(first.Exception.InnerExceptions);
    else if (first.IsCanceled) tcs.TrySetCanceled();
    else
    {
      try
      {
        next().ContinueWith(__ =>
        {
          if (t.IsFaulted) tcs.TrySetException(t.Exception.InnerExceptions);
          else if (t.IsCanceled) tcs.TrySetCanceled();
          else tcs.TrySetResult(null);
        }, TaskContinuationOptions.ExecuteSynchronously);
      }
      catch (Exception exc) { tcs.TrySetException(exc); }
    }
  }, TaskContinuationOptions.ExecuteSynchronously);
  return tcs.Task; 
}

您可以使用它作为这样的:

You can use it as such:

var task = FooAsync().Then(() => BarAsync()).Then(() => FubarAsync());
task.ContinueWith(t =>
{
  if (t.IsFaulted || t.IsCanceled)
  {
    var e = t.Exception.InnerException;
    // exception handling
  }
  else
  {
    Console.WriteLine("All done");
  }
}, TaskContinuationOptions.ExcecuteSynchronously);


使用接收,它看起来像这样(假设你不已经暴露的IObservable和其中的异步方法;单元&gt; ):


Using Rx, it would look like this (assuming you don't have the async methods already exposed as IObservable<Unit>):

FooAsync().ToObservable()
    .SelectMany(_ => BarAsync().ToObservable())
    .SelectMany(_ => FubarAsync().ToObservable())
    .Subscribe(_ => { Console.WriteLine("All done"); },
        e => { Console.WriteLine(e); });

我想。我不是一个接收主,以任何方式。 :)

I think. I'm not an Rx master, by any means. :)

这篇关于异步任务的顺序处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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