When should Task.ContinueWith be called with TaskScheduler.Current as an argument?

前端 未结 4 458
悲&欢浪女
悲&欢浪女 2021-02-02 15:03

We are using this code snippet from StackOverflow to produce a Task that completes as soon as the first of a collection of tasks completes successfully. Due to the non-linear na

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2021-02-02 15:46

    Probably you need to choose a task scheduler that is appropriate for actions that an executing delegate instance performs.

    Consider following examples:

    Task ContinueWithUnknownAction(Task task, Action actionOfTheUnknownNature)
    {
        // We know nothing about what the action do, so we decide to respect environment
        // in which current function is called
        return task.ContinueWith(actionOfTheUnknownNature, TaskScheduler.Current);
    }
    
    int count;
    Task ContinueWithKnownAction(Task task)
    {
        // We fully control a continuation action and we know that it can be safely 
        // executed by thread pool thread.
        return task.ContinueWith(t => Interlocked.Increment(ref count), TaskScheduler.Default);
    }
    
    Func cpuHeavyCalculation = () => 0;
    Action printCalculationResultToUI = task => { };
    void OnUserAction()
    {
        // Assert that SynchronizationContext.Current is not null.
        // We know that continuation will modify an UI, and it can be safely executed 
        // only on an UI thread.
        Task.Run(cpuHeavyCalculation)
            .ContinueWith(printCalculationResultToUI, TaskScheduler.FromCurrentSynchronizationContext());
    }
    

    Your FirstSuccessfulTask() probably is the example where you can use TaskScheduler.Default, because the continuation delegate instance can be safely executed on a thread pool.

    You can also use custom task scheduler to implement custom scheduling logic in your library. For example see Scheduler page on Orleans framework website.

    For more information check:

    • It's All About the SynchronizationContext article by Stephen Cleary
    • TaskScheduler, threads and deadlocks article by Cosmin Lazar
    • StartNew is Dangerous article by Stephen Cleary

提交回复
热议问题