【问题标题】:How to throw an exception in an async method (Task.FromException)如何在异步方法中引发异常 (Task.FromException)
【发布时间】:2017-06-03 19:53:19
【问题描述】:

我刚刚发现,从 .NET 4.6 开始,Task 对象上有一个新方法 FromException,我想知道在 async 方法中抛出异常的最佳方法是什么。

这里有两个例子:

internal class Program
{
    public static void Main(string[] args)
    {
        MainAsync().Wait();
    }

    private static async Task MainAsync()
    {
        try
        {
            Program p = new Program();
            string x = await p.GetTest1(@"C:\temp1");
        }
        catch (Exception e)
        {
            // Do something here
        }
    }

    // Using the new FromException method
    private Task<string> GetTest1(string filePath)
    {
        if (!Directory.Exists(filePath))
        {
            return Task.FromException<string>(new DirectoryNotFoundException("Invalid directory name."));
        }
        return Task.FromResult(filePath);
    }

    // Using the normal throw keyword
    private Task<string> GetTest2(string filePath)
    {
        if (!Directory.Exists(filePath))
        {
             throw new DirectoryNotFoundException("Invalid directory name.");
        }
        return Task.FromResult(filePath);
    }
}

【问题讨论】:

  • async 方法中抛出异常的最佳方法是throw。但是,您的示例都不是async 方法。

标签: c# .net exception async-await task


【解决方案1】:

GetTest1()GetTest2 之间的行为有所不同。

GetTest1()在调用方法时不会抛出异常。相反,它返回一个Task&lt;string&gt;。在等待该任务之前不会引发异常(我们也可以选择检查任务以查看是否成功,而无需引发异常)。

相比之下,GetTest2() 在调用时会立即抛出异常,而不会返回 Task&lt;string&gt;

我猜你使用哪一个取决于所需的行为。如果我有一堆GetTest() 任务,我想并行运行,并且我希望继续执行那些成功的任务,那么我将使用Task.FromException,它允许我检查每个任务的结果并采取相应的行动。相反,如果列表中的任何异常意味着我不想继续执行,我可能会抛出异常。

【讨论】:

  • 最后一段没有意义。 Task.FromException 根本不应该在 async 方法中使用。
  • @StephenCleary 删除了有问题的段落 - 感谢您指出
  • @Stephen Cleary 为什么不呢?例如:private async Task&lt;string&gt; GetTest3(string filePath) { if (!Directory.Exists(filePath)) { return await Task.FromException&lt;string&gt;(new DirectoryNotFoundException("Invalid directory name.")); } ... }
  • @Bidou:因为await Task.FromException&lt;string&gt;(new DirectoryNotFoundException("Invalid directory name."));return 不会编译)只是表达throw new DirectoryNotFoundException("Invalid directory name."); 的一种过于冗长的方式
  • @Stephen Cleary 好的,谢谢,这就是我的猜测。顺便说一句,它与return 编译得很好,但这是一个细节......
猜你喜欢
  • 2011-07-19
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多