如果返回任务的方法抛出异常? [英] Should methods that return Task throw exceptions?

查看:167
本文介绍了如果返回任务的方法抛出异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

返回工作有两种选择报告的错误方法:

Methods that return Task have two options for reporting an error:

  1. 在抛出异常的时候了
  2. 在返回将与除了完成任务

如果主叫方希望这两种类型的错误报告,或者是有一些标准/协议限制任务行为的第二个选项?

Should the caller expect both types of error reporting or is there some standard/agreement that limits task behavior to the second option?

例如:

class PageChecker {
     Task CheckWebPage(string url) {
        if(url == null) // argument check            
            throw Exception("Bad url");                     

        if(!HostPinger.IsHostOnline(url)) // some other synchronous check           
            throw Exception("Host is down");            

        return Task.Factory.StartNew(()=> {
            // asynchronous check                
            if(PageDownloader.GetPageContent(url).Contains("error")) 
                throw Exception("Error on the page");
        });
     }
}

处理两种类型看起来pretty的丑陋:

Handling both types looks pretty ugly:

try {
    var task = pageChecker.CheckWebPage(url);

    task.ContinueWith(t => 
        {
            if(t.Exception!=null)
                ReportBadPage(url);
        }); 

}
catch(Exception ex) {
    ReportBadPage(url);
}

使用异步/等待可能会有帮助,但有对于普通的.NET 4的解决方案,而不异步支持?

Using async/await may help, but is there a solution for plain .net 4 without async support?

推荐答案

大多数工作 -returning方法适用于具有使用异步 / 等待(,因此不应该使用 Task.Run 任务.Factory.StartNew 内部)。

Most Task-returning methods are intended for use with async/await (and as such should not use Task.Run or Task.Factory.StartNew internally).

请注意,与调用异步方法的常用的方式,它并不重要的例外是如何引发

Note that with the common way of calling asynchronous methods, it doesn't matter how the exception is thrown:

await CheckWebPageAsync();

所不同的只是来当该方法被调用,然后等待后面:

The difference only comes in when the method is called and then awaited later:

List<Task> tasks = ...;
tasks.Add(CheckWebPagesAsync());
...
await Task.WhenAll(tasks);

不过,通常是呼叫( CheckWebPagesAsync())和等待在$ C的同一个块$ C,所以他们会在同一个尝试 / 反正块,而在这种情况下,它也(通常)没有关系。

However, usually the call (CheckWebPagesAsync()) and the await are in the same block of code, so they would be in the same try/catch block anyway, and in that case it also (usually) doesn't matter.

有没有一些标准/协议限制任务行为的第二个选项?

is there some standard/agreement that limits task behavior to the second option?

没有标准。 preconditions是一类愚蠢的例外的,所以它其实并不重要,它是如何抛出,因为它的不应该被抓反正。

There is no standard. Preconditions are a type of boneheaded exception, so it doesn't really matter how it's thrown because it should never be caught anyway.

乔恩斯基特是preconditions应直接抛出的观点(外返回的任务):

Jon Skeet is of the opinion that preconditions should be thrown directly ("outside" the returned task):

Task CheckWebPageAsync(string url) {
  if(url == null) // argument check            
    throw Exception("Bad url");                     

  return CheckWebPageInternalAsync(url);
}

private async Task CheckWebPageInternalAsync(string url) {
  if((await PageDownloader.GetPageContentAsync(url)).Contains("error")) 
    throw Exception("Error on the page");
}

这提供了一个很好的平行LINQ运营商,这些都保证了异常的早像这样(枚举外)。

This provides a nice parallel to LINQ operators, which are guaranteed to throw exceptions "early" like this (outside the enumerator).

但我不认为这是必要的。我发现任务中抛preconditions当code是简单的:

But I don't think that's necessary. I find the code is simpler when throwing preconditions within the task:

async Task CheckWebPageAsync(string url) {
  if(url == null) // argument check            
    throw Exception("Bad url");                     

  if((await PageDownloader.GetPageContentAsync(url)).Contains("error")) 
    throw Exception("Error on the page");
}

记住,应永远不会有任何code映入preconditions ,所以在现实世界中,应该没有任何区别的异常是如何抛出。

Remember, there should never be any code that catches preconditions, so in the real world, it shouldn't make any difference how the exception is thrown.

在另一方面,这种的的一个点上,我居然跟乔恩斯基特不同意。所以,你的里程可能会有所不同...很多。 :)

On the other hand, this is one point where I actually disagree with Jon Skeet. So your mileage may vary... a lot. :)

这篇关于如果返回任务的方法抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆