Understanding context in C# 5 async/await

前端 未结 2 1157
北海茫月
北海茫月 2020-12-02 11:37

Am I correct that async/await itself has nothing to do with concurrency/parallelism and is nothing more than continuation-passing style (CPS) implementation? And the real th

2条回答
  •  广开言路
    2020-12-02 12:15

    No, the async/await keywords have everything to do with concurrency. async/await basically wrap your method code in to a task and continuation. To see the exact translation that the compiler produces (using the Task Parallel Library) disassemble some code snippet. This translation of async/await usage is 'similar' (but not identical!) to the example below

    async Task TaskOfTResult_MethodAsync()
    {
        int hours;
        // . . .
        // Return statement specifies an integer result.
        return hours;
    }
    
    // Calls to TaskOfTResult_MethodAsync
    Task returnedTaskTResult = TaskOfTResult_MethodAsync();
    int intResult = await returnedTaskTResult;
    // or, in a single statement
    int intResult = await TaskOfTResult_MethodAsync();
    

    this is approxiamtely converted to

    private int Result()
    {
        int hours;
        // . . .
        // Return statement specifies an integer result.
        return hours;
    }
    

    where you wait for the return outside of the method like

    int? hours = null;
    Task task = null;
    task = Task.Factory.StartNew(() => Result());
    task.ContnueWith(cont => 
    {
        // Some task completion checking...
        hours = task.Result;
    }, CancellationToken.None, 
       TaskCreationOptions.None, 
       TaskScheduler.Current);
    

    Or, you could place the TPL code into the Result method

    private int ResultAsync()
    {
        int? hours = null;
        Task task = null;
        task = Task.Factory.StartNew(() => 
        {
            int hours;
            // . . .
            // Return statement specifies an integer result.
            return hours;
        }, CancellationToken.None, 
           TaskCreationOptions.None, 
           TaskScheduler.Current);
        try
        {
            return task.Result;
        }
        catch (AggregateException aggEx)
        {
            // Some handler method for the agg exception.
            aggEx.Handle(HandleException); 
        }
    }
    

    SynchronizationContext does not guarantee that continuation will be executed on the same thread for the async/awate code. However, you can set the context using TPL code, via the SynchronisationContex keyword.

提交回复
热议问题