【发布时间】:2013-01-21 21:55:10
【问题描述】:
伙计们,我发现自己处于一个奇怪的境地。我需要将不同返回类型的任务链接在一起。通常,你可以这样做
Task<T> t = Task<T>.Factory.StartNew(() => ... some T instance);
Task t2 = t.ContinueWith<U>(parent => ...);
return Task.WhenAll(t, t2);
然而,我的复杂之处在于使用 FromAsync 辅助方法来包装 Begin/End 对并将其转换为任务。我正在尝试使用 HttpWebRequest 和 .NET 4.0 上的任务编写异步客户端(因此 await 不是一个选项)。
我的问题是 FromAsync 的返回类型是一个 Task 本身,它阻止我在 ContinueWith 方法中使用它(ContinueWith 需要返回类型并将数据本身包装在 Task 对象中) .
这是我到目前为止的代码,它产生了正确的函数结果,但不是真正的异步:
public Task<string> GetHttpRequest(string url, string contentType)
{
var httpWebRequest = CreateHttpWebRequest(url, "GET", contentType);
Task<WebResponse> httpTask = Task.Factory.FromAsync<WebResponse>(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
return httpTask.ContinueWith(httpAntecedent =>
{
WebResponse webResponse = httpAntecedent.Result;
Stream responseStream = webResponse.GetResponseStream();
byte[] data = new byte[webResponse.ContentLength];
var streamReadTask = Task<int>.Factory.FromAsync(responseStream.BeginRead, responseStream.EndRead, data, 0, data.Length, TaskCreationOptions.AttachedToParent);
return streamReadTask.ContinueWith(parent =>
{
responseStream.Close();
webResponse.Close();
return Encoding.UTF8.GetString(data);
});
}).Result;
}
【问题讨论】:
-
return Task.WhenAll(t, t2);Task.WhenAll 没有这样的过载。 -
@HamletHakobyan 当然可以,那是因为它是
params方法(至少在 .Net 4.5 上,在 4.0 上,根本没有WhenAll())。 -
如果你使用VS2012和Microsoft.Bcl.Async,你可以在.Net 4.0上使用
await。
标签: c# task-parallel-library async-await