是在多个任务中编辑一个哈希集(一次?)线程安全吗?

时间:2015-11-17 14:33:30

标签: c# multithreading asynchronous concurrency async-await

我有一个必须创建RegistrationInput的应用程序。在每个输入中我转变为RegistrationInput我将ID保存在整数的散列集中,以确保我永远不会多次处理相同的输入。我需要异步地进行输入数组的registrationinputs,但如果我在创建RegistrationInputs之一时看到任何值不正确,我返回null并从hashset中删除ID。

我正在做的是线程安全的吗?这也是异步处理数据的最佳方法吗?我已经使用Parallel.Foreach lambda尝试async但是返回async无效,所以我无法等待它。

Inputs[] events = GetInputs();
List<Task<RegistrationInput>> tasks = new List<Task<RegistrationInput>>();
foreach (var ev in events)
    tasks.Add(ProcessEvent(ev));

tempInputs = await Task.WhenAll<RegistrationInput>(tasks);

2 个答案:

答案 0 :(得分:4)

  

我做的是线程安全的吗?

不,HashSet<T> is not thread-safe。如果您需要从多个线程修改它,您需要使用lock

  

此类型的任何公共静态(在Visual Basic中为Shared)成员都是   线程安全。 不保证任何实例成员都是线程   安全

您可以做的最好的事情是让这些并发操作完全不知道彼此,并且有一些更高级别的机制,确保不会两次查询两个ID。

  

这也是异步处理数据的最佳方式吗?

在我看来,你是在正确的轨道上同时为每个事件执行ProcessEvent。我唯一想做的就是重新编写foreach循环来使用Enumerable.Select,但这是一个风格问题:

Inputs[] events = GetInputs();
var tasks = events.Select(ev => ProcessEvent(ev));
tempInputs = await Task.WhenAll<RegistrationInput>(tasks);

答案 1 :(得分:1)

您可以使用ConcurentDictionary<ProcessEvent, byte>并使用Keys。 使用byte作为Value的类型是为了最小化使用的内存量。如果您没有任何内存注意事项,则可以使用其他任何内容。

它是线程安全的,您可以在HashSet

中拥有所有功能