我对结合任务并行库和延续有效地使用系统资源感兴趣。
考虑以下场景,它使用GetResponseAsync()另一个最近的问题中定义的扩展方法。
WebRequest request = HttpWebRequest.Create(uri);
Task<WebResponse> responseTask = request.GetResponseAsync(cancellationToken);
Func<Task<WebResponse>, WebResponse> continuation =
task =>
{
WebRequest followup = HttpWebRequest.Create(uri2);
return followup.GetResponseAsync(cancellationToken).Result;
};
Task<WebResponse> finalResultTask = responseTask.ContinueWith(continuation, cancellationToken);
这种配置存在多个问题,我想知道如何最好地处理它。到目前为止,我确定的主要项目是:
内核的执行
responseTask通过在异步执行期间不阻塞用户线程来有效地使用资源。但是,由于continuation被定义为Funclambda,所以执行continuation的线程会阻塞return在行上,直到后续请求的执行完成。更好的情况是在不阻塞用户线程的情况下提供类似延续的行为。关于取消的行为
responseTask和finalResultTask不同。如果在responseTask执行过程中取消操作,responseTask将进入状态TaskStatus.Canceled。但是,如果在执行过程中取消了操作,那么finalResultTask访问该属性的尝试Result将导致异常,从而导致任务进入TaskStatus.Failed状态。- 在失败方面,行为也可能不同。如果在从延续返回
AggregateException时尝试访问属性时抛出an ,则可能有一个双重包装的真正内部异常(我不确定这里是否发生特殊情况),其中的属性将提供对实际异常应该在第一个任务期间失败。ResultfinalResultTaskInnerExceptionresponseTask.Exception
- 在失败方面,行为也可能不同。如果在从延续返回