我使用下面的Parallel.For
代码调用异步方法。现在看代码它是非常直接的,除了JsonParse类有一个静态方法,它只是调用Web服务来下载json字符串并将其转换为PairResults对象并返回。
我遇到的问题是Parallel.For
循环永不退出,我可以清楚地看到数据来自网络聊天" item.part1 = data.value"一切正常,但updateAllResults永远不会完成。我做错了什么?
public void updateAllResults()
{
Parallel.For(0, PairList.Count(), (i) =>
{
var item = PairList[i];
var data = (Parse.JsonParse<PairResults>
.getJsonString("http://localhost:22354/"
+ item.Original)).Result;
item.part1 = data.value;
});
}
答案 0 :(得分:5)
这是Parallel.For
的反模式,因为您只是使用它来启动异步操作并阻止它们。这样,它将阻止有限数量的池线程,并且实际的并行度可能比使用任务时要低得多:
public void updateAllResults()
{
var tasks = PairList.Select(async (item) =>
{
var data = await Parse.JsonParse<PairResults>
.getJsonString("http://localhost:22354/" + item.Original).
.ConfigureAwait(false);
item.part1 = data.value;
});
Task.WaitAll(tasks.ToArray());
}
此外,您的问题标有winforms标记。如果您在WinForms应用程序中使用它,Parallel.For
和上面的代码都将阻止您的UI线程。正确的解决方案是使用Task.WhenAll
:
public async Task updateAllResults()
{
var tasks = PairList.Select(async (item) =>
{
var data = await Parse.JsonParse<PairResults>
.getJsonString("http://localhost:22354/" + item.Original)
.ConfigureAwait(false);
item.part1 = data.value;
});
await Task.WhenAll(tasks.ToArray());
}
// button click handler
async void button_Click(object s, EventArgs e)
{
this.button.Enabled = false;
try
{
await updateAllResults()
}
finally
{
this.button.Enabled = true;
}
}
答案 1 :(得分:2)
Parallel.For块直到所有迭代都已执行或者循环中断,就像常规for
语句一样。确保已下载所有数据。之后Parallel.For
应该完成,因此也就是方法。