【发布时间】:2020-04-06 19:36:07
【问题描述】:
假设我有以下代码:
class Test
{
Dictionary<int, Task> tasks;
void Run()
{
tasks.Add(1, DoStuff(1));
tasks.Add(2, DoStuff(2));
tasks.Add(3, DoStuff(3));
}
async Task DoStuff(int id)
{
try
{
// Do stuff that takes a lot of time and can end unsuccessfully.
}
finally
{
tasks.Remove(id);
}
}
}
如果我确定该任务只能删除它自己并且所有 id 都会不同(例如新生成的 guid) - 我可以保留此代码吗?还是我需要某种锁定或在这里使用 ConcurrentDictionary 因为常规 Dictionary 或 List 的内部在同时访问时可能会失败? (假设有 10000 个这样的任务,它们都同时结束)
另外:没有人会阅读这个字典/列表或遍历它。它仅用于保留对后台任务的引用(因此 GC 不会收集它们)。如果您对该用例有更好的建议,欢迎提出建议:)
【问题讨论】:
-
你不需要加锁就可以从the documentation中移除...:"如果
Dictionary<TKey,TValue>不包含具有指定key的元素,Dictionary<TKey,TValue>保持不变. 不会抛出异常。” 然而,这并不意味着它是线程安全的。 -
"仅限 .NET Core 3.0+:可以安全地调用此变异方法,而不会使 Dictionary
实例上的活动枚举数无效。这并不意味着线程安全。"阅读最后一行... -
打错了,谢谢。我会修复
标签: c# asynchronous collections concurrency thread-safety