Should methods that return Task throw exceptions?

╄→гoц情女王★ 提交于 2019-12-04 00:05:52

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);

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?

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.

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");
}

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

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");
}

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. :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!