几个小时后,我在C#中遇到异步代码,我无法理解为什么我的代码陷入僵局。 到目前为止,我已经发了许多文章,并为我敲响了任何东西。
希望你能帮助我。
这是我试图运行的代码。
主要
Task.Run(async () =>
{
Task<EventDetailed[]> events = getDetailedEvents();
await events;
}).Wait();
getDetailedEvents:
static async Task<EventDetailed[]> getDetailedEvents()
{
...
EventDetailed[] result = await LoadDetailedEventsDetailsAsync(evnts).ConfigureAwait(false);
return result;
}
我问题的核心。
LoadDetailedEventsDetailsAsync
async static Task<EventDetailed[]> LoadDetailedEventsDetailsAsync(Event[] events)
{
List<EventDetailed> detailed = new List<EventDetailed>();
List<Task<WebResponse>> responses = new List<Task<WebResponse>>();
List<Event> tasksWithStream = new List<Event>();
foreach (Event e in events)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://...");
... some headers etc ...
e.Stream = httpWebRequest.GetRequestStreamAsync();
e.WebRequest = httpWebRequest;
tasksWithStream.Add(e);
}
foreach (var tsk in tasksWithStream)
{
try {
await tsk.Stream.ConfigureAwait(false);
using (var streamWriter = new StreamWriter(tsk.Stream.Result))
{
streamWriter.Write("...");
streamWriter.Flush();
streamWriter.Close();
}
responses.Add(tsk.WebRequest.GetResponseAsync());
}
catch (Exception ex)
{
Logger.mes("Failed to get event data.");
}
}
foreach (var response in responses)
{
try
{
await response.ConfigureAwait(false);
}
catch (Exception ex)
{
Logger.mes("Failed to get event data.");
continue;
}
parseData.Add(ParseData(response));
}
答案 0 :(得分:1)
几点:
首先,重要的是要注意你应该几乎永远不会在异步任务上调用.Wait
(或.Result
) - 你应该使用{{1相反。其中一个非常的例外情况是在控制台应用的await
方法中。原因是如果你不阻止主线程,你的程序就会过早退出。
其次,如果您需要发出多个不相互依赖的HTTP请求(即请求B不需要请求A的结果),那么通过并行执行它们可以获得巨大的性能提升。更好的是,您不会为每个请求消耗一个线程,因为调用是异步的,即它们在等待响应时不会阻塞线程,因此同一个线程可以有效地触发许多并发请求。
我不会重新编写您的代码,但我会建议我如何对其进行重组:
Main