【发布时间】:2021-07-17 20:34:04
【问题描述】:
我正在编写从服务器获取不同数据部分的代码,将它们存储在 dict 中,以便它们按正确的顺序排列,然后在获取所有数据后将它们组合起来。但由于某种原因,它不起作用。它在获取所有内容之前进入CombineDataParts()。我不明白我做错了什么,因为所有方法都在等待。请帮忙!
public async Task<Data> GetTableData(List<string> partNames)
{
List<Task> TaskList = new List<Task>();
SortedDictionary<string, Data> dataList = new SortedDictionary<string, Data>();
foreach (var name in partNames)
{
TaskList.Add(SaveDatainDict(name, DataList));
}
await Task.WhenAll(TaskList);
return CombineDataParts(tableDataList.Select(t => t.Value).ToList());
}
private async Task SaveDatainDict(string part, SortedDictionary<string, Data> dataList)
{
dataList[part] = await GetDataPart(part);
}
private async Task<Data> GetDataPart(string key)
{
using (var response = await client.GetData(key))
{
return ProcessData(response.Stream);
}
}
【问题讨论】:
-
SortedDictionary<K,V>类不是线程安全的。您能否尝试在SaveDatainDict方法的开头添加lock (dataList),看看是否有什么不同? -
@TheodorZoulias:这是个糟糕的主意。使用
SortedDictionary需要锁定dataList[part] = (something);操作,但您建议在await GetDataPart(part)期间也持有锁定 -
老实说,我认为这不是字典线程问题。我猜所有的
keys 都是独一无二的?我很好奇您是否在return CombineDataParts行上设置了断点,如果您在TaskList中看到正确数量的任务并且所有IsCompletedSuccessfully的值为true。他们中的任何一个都有例外吗? -
如果它是线程问题,您能否通过保留
GetDataPart中的List<Task<Data>>来消除中间数据结构和方法?然后Task.WhenAllwill return an array ofData可以在其上运行Select语句。 -
@BenVoigt 是的,你是对的。只是按照我建议的方式添加
lock可能甚至无法编译。
标签: c# .net multithreading asynchronous async-await