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

标签 c# multithreading asynchronous concurrency async-await

我有一个必须创建 RegistrationInput 的应用程序。对于每个我要转换为 RegistrationInput 的输入,我将 ID 保存在整数哈希集中,以确保我不会多次处理相同的输入。我需要异步创建输入数组的注册输入,但如果在创建其中一个注册输入期间发现任何值不正确,我会返回 null 并从中删除 ID哈希集。

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

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);

最佳答案

Is what I'm doing thread-safe?

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

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

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

Also is this the best way to asynchrously process data?

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

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

关于c# - 在多个任务中(一次?)编辑哈希集是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33759519/

相关文章:

multithreading - 使用 channel 和线程时我要等待或加入什么?

java - 当异步方法中某个线程发生异常时终止所有线程

c++ - Windows CE 5 和 6 之间的互锁 API

javascript - ASP.Net MVC - 使用 href 从 View 传递参数

c# - 使用 MVC 进行依赖注入(inject)和内存中集成测试

C#:最佳实践 Debug.Print

c# - 线程中的定时器问题

javascript - React组件类,不能写async方法?

javascript - 我怎样才能从捕获中返回一个 Promise 然后拒绝下一个捕获?

c# - 使用 WinSCP 对远程 SFTP 文件夹中的文件进行计数