Unhandled async exception

Reasons to avoid async voidaside, is it possible to catch the following error from calling the code?

private static Action ErrorAction
{
  get
  {
    return async () =>
    {
      await Task.Delay(0);
      throw new NotImplementedException();
    };
  }
}

For example, in both of the following cases, I would like to get an exception, but both tests fail:

[Test]
public void SelfContainedExampleTryCatch()
{
  List<Exception> errors = new List<Exception>();
  try
  {
     ErrorAction();
  }
  catch (Exception ex)
  {
    errors.Add(ex);
  }
  errors.Count().Should().Be(1);
}

[Test]
public void SelfContainedExampleContinueWith()
{
  List<Exception> errors = new List<Exception>();
  var task = Task.Factory.StartNew(ErrorAction);
  task.ContinueWith(t =>
                {
                    errors.Add(t.Exception);
                }, TaskContinuationOptions.OnlyOnFaulted);
  task.Wait();

  errors.Count().Should().Be(1);
}

I know I could use a method with a signature async Task; but, in particular, it is that you need to process the argument of the asynchronous code of the delegate assigned to Action, which I need to process, and it is almost impossible to catch globally. If possible, a solution common to synchronous and asynchronous actions would be ideal.

I hope there is a simple solution that I missed, but so far I have only headed a lot of dead ends and had (possibly wrongly) concluded that this is not possible. Any help (or wasting time saving) will be appreciated!

+4
3

, async void, (, ICommand.Execute). API await -compatible API async void :

static Func<Task> ErrorActionAsync
{
  get
  {
    return async () =>
    {
      await Task.Yield();
      throw new NotImplementedException();
    };
  }
}

private static Action ErrorAction
{
  get
  {
    return async () => { await ErrorActionAsync(); }
  }
}

( await Task.Delay(0) await Task.Yield(), await Task.Delay(0) noop).

ErrorActionAsync, ErrorAction . , ( async void - ErrorAction).

, ErrorAction , , . AsyncContext , :

[Test]
public void SelfContainedExampleTryCatch()
{
  List<Exception> errors = new List<Exception>();
  try
  {
    AsyncContext.Run(() => ErrorAction());
  }
  catch (Exception ex)
  {
    errors.Add(ex);
  }
  errors.Count().Should().Be(1);
}

AsyncContext.Run , async void , async void .

+2

, ErrorAction , , , ErrorAction, Task.

, , . :

private static Task ErrorAction
{
  get
  {
    // Synchronous code here

    return Task.FromResult(true);
  }
}
0

, . . :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;

namespace ConsoleApplication1
    {
    class Program
        {
        static void Main(string[] args)
            {
            SelfContainedExampleTryCatch();
            SelfContainedExampleContinueWith();
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
            }

        public static void SelfContainedExampleTryCatch()
            {
            var errors = new List<Exception>();
            try
                {
                ErrorAction();
                }
            catch (Exception ex)
                {
                errors.Add(ex);
                }
            errors.Count().Should().Be(1);
            }

        public static void SelfContainedExampleContinueWith()
            {
            var errors = new List<Exception>();
            var task = Task.Factory.StartNew(ErrorAction);
            task.ContinueWith(t =>
            {
                errors.Add(t.Exception);
            }, TaskContinuationOptions.OnlyOnFaulted);
            task.Wait();

            errors.Count().Should().Be(1);
            }

        private static Action ErrorAction
            {
            get
                {
                return () => DoTask().Wait();
                }
            }

        private static async Task DoTask() {
            await Task.Delay(0);
            throw new NotImplementedException();
            }
        }
    }

The ContinueWith test passes, but there will be no other test. I think this is your intention.

-2
source

Source: https://habr.com/ru/post/1618210/


All Articles