C# 链接不同返回类型的任务(TPL和HttpWebRequest)
伙计们,我发现自己的处境很奇怪。我需要将不同退货类型的任务链接在一起。通常,你可以这样做C# 链接不同返回类型的任务(TPL和HttpWebRequest),c#,task-parallel-library,async-await,C#,Task Parallel Library,Async Await,伙计们,我发现自己的处境很奇怪。我需要将不同退货类型的任务链接在一起。通常,你可以这样做 Task<T> t = Task<T>.Factory.StartNew(() => ... some T instance); Task t2 = t.ContinueWith<U>(parent => ...); return Task.WhenAll(t, t2); 要重新表述您的问题,您有任务,您希望从中获得任务,而不需要同步等待任务完成 在C#5.
Task<T> t = Task<T>.Factory.StartNew(() => ... some T instance);
Task t2 = t.ContinueWith<U>(parent => ...);
return Task.WhenAll(t, t2);
要重新表述您的问题,您有
任务
,您希望从中获得任务
,而不需要同步等待任务
完成
在C#5.0中,可以通过使用双await
:return-await-task代码>
如果没有C#5.0,您可以使用它,它完全可以做您想要的:returntask.Unwrap()代码>
如果出于某种原因,您想自己做这件事,您可以在ContinueWith()中使用ContinueWith()
以及TaskCompletionSource
但您的代码是有缺陷的:它假设您将在一次读取中获得整个响应。这一点也不能保证,事实上,它通常不会正常工作。正确地执行此操作需要更复杂的代码,并且可能还需要TaskCompletionSource
返回任务
Task.WhenAll没有这样的重载。@HamletHakobyan当然有,那是因为它是一个params
方法(至少在.Net 4.5上,在4.0上,根本没有WhenAll()
)。如果你使用VS2012和,你可以在.Net 4.0上使用wait
。谢谢@svick。“展开”正是我要找的。我引入了一个循环来正确地读取整个响应,但正如您所建议的那样,这显著地改变了代码的结构(我不再需要展开!)
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;
}