c# - C# 异步 REST 查询不起作用:WaitAll 或 WhenAll 结合 .Result 挂起
问题描述
我正在构建一个 C# Winforms 应用程序,并且我有许多 REST 调用要处理。每个电话大约需要 10 秒才能收到答复,所以最后,我的应用程序运行了很长一段时间。主要是花时间等待 REST 服务回答。
我不会挺身而出,因为无论我尝试什么(configureAwait、waitAll 或 whenAll),应用程序都会挂起,或者当我想访问每个任务结果时,它会返回到 Main 方法或挂起。这是我目前拥有的:
我正在建立一个任务列表来填充我的对象:
List<Task> days = new List<Task>();
for (DateTime d = dtStart; d <= dtEnd; d = d.AddDays(1))
{
if (UseProduct)
{
Task _t = AsyncBuildDay(d, Project, Product, fixVersion);
var t = _t as Task<Day>;
days.Add(t);
}
else
{
Task _t = AsyncBuildDay(d, Project, fixVersion);
var t = _t as Task<Day>;
days.Add(t);
}
}
然后我开始等待,直到每个任务完成并构建对象:
Task.WaitAll(days.ToArray());
当我尝试这个时,任务正在等待激活:
var tks = Task.WhenAll(days.ToArray());
在任务(AsyncBuildDay)中异步运行的是对 JIRA 的查询:
private async Task<string> GetResponse(string url)
{
WebRequest request = WebRequest.Create(url);
request.Method = "GET";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(JIRAUser + ":" + JIRAPassword));
request.Credentials = new NetworkCredential(JIRAUser, JIRAPassword);
WebResponse response = await request.GetResponseAsync().ConfigureAwait(false);
// Get the stream containing all content returned by the requested server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content fully up to the end.
string json = reader.ReadToEnd();
return json;
}
现在我想用 .Result 访问我的所有对象,但随后整个代码又冻结了。
foreach (Task<Day> t in days)
{
dc.colDays.Add(t.Result);
}
我没有等待得到我的对象,我真的对这些东西发疯了。任何想法都非常感谢!
解决方案
你把这件事复杂化了。
Task.WhenAll
是要走的路;它返回一个新Task
的,当提供的任务全部完成时完成。
它也是非阻塞的。
通过await
返回Task
by Task.WhenAll
,您将其结果解包到一个数组中:
List<Task<Day>> dayTasks = new();
// ...
Day[] days = await Task.WhenAll(dayTasks);
然后,您可以将其添加到dc.colDays
:
dc.colDays.AddRange(days);
或者如果dc.colDays
没有AddRange
方法:
foreach (var day in days) dc.colDays.Add(day);
推荐阅读
- javascript - 获取移动元素的当前位置 - 鼠标点击
- php - 在laravel中创建新数据时无法按类别保存计算数据
- javascript - 如果名称更改,Javascript 返回 NaN
- java - 如果 a 将对象 A 转换为对象 B,B 是否保留 A 的 ArrayList?
- sql-server - 根据参数从数据库中检索数据
- cassandra - cassandra:它是否自动建立索引,每行列数非常多(宽列)?
- java - 在使用 GSON 反序列化 JSON 的对象类中制作字段/构造函数 PRIVATE 或 PUBLIC 或 NEITHER?
- xamarin.ios - 获取 SSL 证书问题 (Xamarin.ios)
- python - 在 Pandas [CSV 文件] 上执行数学运算:无法将 DataFrame 与
- javascript - 具有动态内容的可转换 div