What happens if I don't await a task?

后端 未结 2 1655
一向
一向 2021-02-01 15:02

Consider this example:

var task = DoSomething()
bool ready = await DoSomethingElse();
if (!ready) 
  return null;

var value = await DoThirdThing(); // depends o         


        
相关标签:
2条回答
  • 2021-02-01 15:27

    Follow-up: Is there a neat way to make sure task is awaited?

    If you need individual, more fine-grained than TaskScheduler.UnobservedTaskException control over exceptions thrown by the tasks you don't await, there is a handy tool for that: async void methods.

    Your code might look like this:

    static async void Observe(Task task)
    {        
        // use try/catch here if desired so;
    
        // otherwise, exceptions will be thrown out-of-band, i.e.
        // via SyncronizationContext.Post or 
        // via ThreadPool.QueueUSerWorkItem (if there's no sync. context) 
    
        await task; 
    }
    
    // ...
    
    var taskObserved = false;
    var task = DoSomething()
    try
    {
        bool ready = await DoSomethingElse();
        if (!ready) 
          return null;
    
        var value = await DoThirdThing(); // depends on DoSomethingElse
        taskObserved = true;
        return value + await task;
     }
     finally
     {
         if (!taskObserved)
            Observe(task);
     }
    

    Some more details can be found here and here.

    0 讨论(0)
  • 2021-02-01 15:33

    The question: What happens to task if we're not ready and exit early?

    Nothing. The code ignores the task, so the task is ignored.

    Will any exceptions that it throws be re-thrown by a SynchronizationContext?

    No. They will (eventually) be passed to TaskScheduler.UnobservedTaskException and then ignored.

    Are there problems if task completes normally, as nobody consumes its value?

    Nope.

    Follow-up: Is there a neat way to make sure task is awaited?

    No.

    Could a finally block be used to await task and re-throw potential exceptions?

    Yes, if your code actually awaits the task. Presumably this would mean saving the task somewhere.

    If task completed normally it would be awaited again in the finally block, but that shouldn't cause any problems?

    You can await a task as many times as you like.

    We could simply await task if we are not ready, however if there were 50 exit conditions this would be very tedious.

    Then consider restructuring your code.

    0 讨论(0)
提交回复
热议问题