我有一个任务来执行HttpWebRequest
使用
Task<WebResponse>.Factory.FromAsync(req.BeginGetRespone, req.EndGetResponse)
这显然会因 a 而失败WebException
。对于调用者,我想返回一个Task<HttpResult>
whereHttpResult
是一个辅助类型来封装响应(或不封装响应)。在这种情况下,4xx 或 5xx 响应也不例外。
因此,我在请求任务中附加了两个延续。一个与TaskContinuationOptions
OnlyOnRanToCompletion
另一个与OnlyOnOnFaulted
。然后将整个事情包裹在 aTask<HttpResult>
中,以获取一个结果,无论哪一个 continuation 完成。
三个子任务(请求加上两个延续)中的每一个都是使用该AttachedToParent
选项创建的。
但是当调用者等待返回的外部任务时,AggregateException
会抛出请求失败。
我想在错误的继续中观察,WebException
以便客户端代码可以查看结果。在 on fault continuation 中添加 aWait
会引发错误,但围绕此问题的 try-catch 无济于事。也不查看该Exception
属性(如“使用 Task.Exception 属性观察异常”部分提示此处)。
我可以安装一个UnobservedTaskException
事件处理程序来过滤,但由于事件没有提供与故障任务的直接链接,这可能会在应用程序的这一部分之外进行交互,并且是一个大锤来破解坚果的情况。
给定一个故障实例,Task<T>
是否有任何方法将其标记为“故障处理”?
简化代码:
public static Task<HttpResult> Start(Uri url) {
var webReq = BuildHttpWebRequest(url);
var result = new HttpResult();
var taskOuter = Task<HttpResult>.Factory.StartNew(() => {
var tRequest = Task<WebResponse>.Factory.FromAsync(
webReq.BeginGetResponse,
webReq.EndGetResponse,
null, TaskCreationOptions.AttachedToParent);
var tError = tRequest.ContinueWith<HttpResult>(
t => HandleWebRequestError(t, result),
TaskContinuationOptions.AttachedToParent
|TaskContinuationOptions.OnlyOnFaulted);
var tSuccess = tRequest.ContinueWith<HttpResult>(
t => HandleWebRequestSuccess(t, result),
TaskContinuationOptions.AttachedToParent
|TaskContinuationOptions.OnlyOnRanToCompletion);
return result;
});
return taskOuter;
}
和:
private static HttpDownloaderResult HandleWebRequestError(
Task<WebResponse> respTask,
HttpResult result) {
Debug.Assert(respTask.Status == TaskStatus.Faulted);
Debug.Assert(respTask.Exception.InnerException is WebException);
// Try and observe the fault: Doesn't help.
try {
respTask.Wait();
} catch (AggregateException e) {
Log("HandleWebRequestError: waiting on antecedent task threw inner: "
+ e.InnerException.Message);
}
// ... populate result with details of the failure for the client ...
return result;
}
(HandleWebRequestSuccess
最终会衍生出进一步的任务来获取响应的内容......)
客户端应该能够等待任务然后查看它的结果,而不会因为预期的和已经处理的错误而抛出它。