ale*_*lex 13 .net c# asynchronous .net-4.0 task-parallel-library
返回的方法Task有两个报告错误的选项:
调用者是否应该期望两种类型的错误报告,或者是否存在将任务行为限制为第二个选项的某些标准/协议?
例:
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");
});
}
}
Run Code Online (Sandbox Code Playgroud)
处理这两种类型看起来很丑陋:
try {
var task = pageChecker.CheckWebPage(url);
task.ContinueWith(t =>
{
if(t.Exception!=null)
ReportBadPage(url);
});
}
catch(Exception ex) {
ReportBadPage(url);
}
Run Code Online (Sandbox Code Playgroud)
使用async/await可能有所帮助,但有没有异步支持的纯.NET 4解决方案?
Ste*_*ary 12
大多数Task退回方法旨在与async/ 一起使用await(因此不应使用Task.Run或Task.Factory.StartNew内部使用).
请注意,使用调用异步方法的常用方法,抛出异常的方式无关紧要:
await CheckWebPageAsync();
Run Code Online (Sandbox Code Playgroud)
差异只发生在调用方法然后等待的时候:
List<Task> tasks = ...;
tasks.Add(CheckWebPagesAsync());
...
await Task.WhenAll(tasks);
Run Code Online (Sandbox Code Playgroud)
但是,通常call(CheckWebPagesAsync())和它们await都在同一个代码块中,所以无论如何它们都在同一个try/ catchblock中,在这种情况下它也(通常)无关紧要.
是否有一些标准/协议将任务行为限制为第二种选择?
没有标准.前提条件是一种类型的骨头异常,所以它抛出的方式并不重要,因为它永远不会被捕获.
Jon Skeet认为应该直接抛出先决条件(返回任务的"外部"):
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");
}
Run Code Online (Sandbox Code Playgroud)
这为LINQ运算符提供了一个很好的并行,它保证像这样"早期"抛出异常(在枚举器之外).
但我不认为这是必要的.在任务中抛出前置条件时,我发现代码更简单:
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");
}
Run Code Online (Sandbox Code Playgroud)
请记住,永远不应该有任何捕获前置条件的代码,因此在现实世界中,抛出异常的方式不应该有任何区别.
另一方面,这是我实际上不同意Jon Skeet的一点.所以你的里程可能会有所不同......很多.:)
| 归档时间: |
|
| 查看次数: |
3690 次 |
| 最近记录: |