【发布时间】:2018-07-01 04:40:40
【问题描述】:
创建任务列表的类,每个任务返回 ConcurrentDictionary
public List<Task<ConcurrentDictionary<int, object>>> GetDictionaries()
{
var results = new ConcurrentDictionary<int, object>();
var tasks = new List<Task<ConcurrentDictionary<int, object>>>();
for (var k = 0; k < 10; k++)
{
tasks.Add(Task.Run(() =>
{
var done = false;
var data = new Object();
var eventCallback = (int id) => { data.id = id; done = true; };
Client.asyncEvent += eventCallback;
Client.initiateAsyncEvent(k);
while (done == false);
Client.asyncEvent -= eventCallback;
results[k] = data;
return results;
}));
}
return tasks;
}
调用事件(任务)10次,等待该事件的回调,将结果添加到字典“results”中。
我们执行 10 个事件(任务),因此应该在字典中获取 10 个项目,但是当我将所有任务的字典与 When.All 合并时,列表包含 100 个项目而不是 10 个。
var tasks = GetDictionaries();
var plainListOfResults = Task
.WhenAll(tasks)
.Result
.SelectMany(o => o.Keys)
.ToList();
// Expected: [0,1,2,3,4,5,6,7,8,9]
// Actual: [0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9 ... 0,1,2,3,4,5,6,7,8,9]
问题
- 为什么 10 个任务创造的结果是应有的 10 倍?
- 为什么,当我将 ConcurrentDictionary 替换为 Dictionary 时,此代码会按预期工作?
【问题讨论】:
-
这是一大堆代码,其中大部分与问题无关,您能否创建一个最小的示例来解释您要解释的内容?因为它不明显
-
@TheGeneral 试图简化代码并重新表述问题。
-
直觉上,我认为 Dictionary 和 ConcurrentDictionary 在如何合并具有相同键的项目方面存在差异。看起来 ConcurrentDictionary 为每个线程创建了同一个字典的实例,当我合并线程时会导致 When.All 它认为所有对象都是唯一的,即使使用相同的键也是如此。
标签: c# multithreading concurrency interactive-brokers tws