Sequential processing of asynchronous tasks

前端 未结 5 578
旧时难觅i
旧时难觅i 2020-12-08 02:53

Assume the following synchronous code:

try
{
    Foo();
    Bar();
    Fubar();
    Console.WriteLine(\"All done\");
}
catch(Exception e) // For illustration         


        
5条回答
  •  隐瞒了意图╮
    2020-12-08 03:22

    You should be able to create a method to combine two tasks, and only start the second if the first succeeds.

    public static Task Then(this Task parent, Task next)
    {
        TaskCompletionSource tcs = new TaskCompletionSource();
        parent.ContinueWith(pt =>
        {
            if (pt.IsFaulted)
            {
                tcs.SetException(pt.Exception.InnerException);
            }
            else
            {
                next.ContinueWith(nt =>
                {
                    if (nt.IsFaulted)
                    {
                        tcs.SetException(nt.Exception.InnerException);
                    }
                    else { tcs.SetResult(null); }
                });
                next.Start();
            }
        });
        return tcs.Task;
    }
    
    
    

    you can then chain tasks together:

    Task outer = FooAsync()
        .Then(BarAsync())
        .Then(FubarAsync());
    
    outer.ContinueWith(t => {
        if(t.IsFaulted) {
            //handle exception
        }
    });
    

    If your tasks are started immediately you can just wrap them in a Func:

    public static Task Then(this Task parent, Func nextFunc)
    {
        TaskCompletionSource tcs = new TaskCompletionSource();
        parent.ContinueWith(pt =>
        {
            if (pt.IsFaulted)
            {
                tcs.SetException(pt.Exception.InnerException);
            }
            else
            {
                Task next = nextFunc();
                next.ContinueWith(nt =>
                {
                    if (nt.IsFaulted)
                    {
                        tcs.SetException(nt.Exception.InnerException);
                    }
                    else { tcs.SetResult(null); }
                });
            }
        });
        return tcs.Task;
    }
    
        

    提交回复
    热议问题