Why doesn't this exception get thrown?

前端 未结 3 1866
醉话见心
醉话见心 2020-12-10 16:26

I use a set of tasks at times, and in order to make sure they are all awaited I use this approach:

public async Task ReleaseAsync(params Task[] TaskArray)
{
         


        
3条回答
  •  感动是毒
    2020-12-10 16:41

    From the comment:

    these [tasks] were tied to managed resources and I wanted to release them when they became available instead of waiting for all of them to complete and then releasing.

    Using a helper async void method may give you the desired behavior for both removing the finished tasks from the list and immediately throwing unobserved exceptions:

    public static class TaskExt
    {
        public static async void Observe(Task task)
        {
            await task;
        }
    
        public static async Task WithObservation(Task task)
        {
            try
            {
                return await task;
            }
            catch (Exception ex)
            {
                // Handle ex
                // ...
    
                // Or, observe and re-throw
                task.Observe(); // do this if you want to throw immediately
    
                throw;
            }
        }
    }
    

    Then your code might look like this (untested):

    async void Main()
    {
        Task[] TaskArray = new Task[] { run().WithObservation() };
        var tasks = new HashSet(TaskArray);
        while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks));
    }
    

    .Observe() will re-throw the task's exception immediately "out-of-band", using SynchronizationContext.Post if the calling thread has a synchronization context, or using ThreadPool.QueueUserWorkItem otherwise. You can handle such "out-of-band" exceptions with AppDomain.CurrentDomain.UnhandledException).

    I described this in more details here:

    TAP global exception handler

提交回复
热议问题