Handling exceptions from the synchronous part of async method

后端 未结 2 426
一个人的身影
一个人的身影 2021-01-13 03:05

I\'m dealing with the situation where the task I start may throw, while still executing synchronously on the initial thread. Something like this, for illustrative purposes:

相关标签:
2条回答
  • 2021-01-13 03:28

    I'd split it into two parts, rather than relying on task.GetAwaiter().GetResult() to work. I'd be afraid that someone maintaining TestAsync could unwittingly break things in the future.

    This is how I would write it. This should preserve the behavior you've got, but I find it more obvious what's going on:

    static Task Test()
    {
        var random = new Random(Environment.TickCount).Next();
        if (random % 2 != 0)
            throw new ApplicationException("1st");
    
        return TestAsync();
    }
    
    static async Task TestAsync()
    {
        await Task.Delay(2000);
        Console.WriteLine("after await Task.Delay");
        throw new ApplicationException("2nd");
    }
    
    
    
    static void Main(string[] args)
    {
        try
        {
            Test();
            Console.WriteLine("TestAsync continues asynchronously...");
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.ToString());
        }
    
        Console.WriteLine("Press Enter to exit...");
        Console.ReadLine();
    }
    
    0 讨论(0)
  • 2021-01-13 03:35

    Generally speaking, exceptions should not be used for routine error handling in your application. Throw exceptions for "exceptional" circumstances, where the program cannot continue because something unexpected happened and you need to do a hard stop.

    Granted, I do not know precisely what your use case is, but whenever I'm using async tasks, the piece that is going to fail unexpectedly is usually also the piece that should be asynchronous (e.g. connecting to a database).

    Regardless, how I would do this is to put your TestAsync method into its own class. Then, you can have a method (or property) bool TestAsync.IsValid to determine whether the task is ready to go and should be queued for execution; then, you can run your async task if the answer is true: TestAsync.RunAsync().

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