c# - ManualResetEvent 的可能竞争条件

标签 c# multithreading

问题:

我正在尝试从 ThreadPool 中抛出 6 个线程来处理单个任务。每个任务的ManualResetEvent 都存储在一个手动重置事件数组中。线程数对应ManualResetEvent数组中的索引。

现在发生的事情是,一旦我启动了这 6 个线程,我就移出并等待线程完成。等待线程是在主线程中完成的。

现在有时发生的情况是我的等待逻辑即使在很长一段时间后(我已经看到了 2 天)也没有返回。这是线程等待逻辑的代码示例

                foreach (ManualResetEvent whandle in eventList)
                {
                    try
                    {
                        whandle.WaitOne();
                    }
                    catch (Exception) { }
                }

根据 .WaitOne 的文档。如果未从线程接收到 Set 事件,则同步调用使线程不返回。

有时我的线程的工作量较少,它们甚至可能在我到达 Wait 逻辑之前返回。 .WaitOne() 是否有可能等待 Set() 事件,即使它是过去收到的? 这是等待所有线程关闭的正确逻辑吗?

最佳答案

我没有直接回答这个问题。这是您应该做的:

使用 Task.Factory.StartNew 启动任务并使用 Task.WaitAll(Task[]) 等待它们。您不必以这种方式处理事件。异常将很好地传播到“ fork ”线程。您不再需要旧的 ThreadPool API。

希望这对您有所帮助。

关于c# - ManualResetEvent 的可能竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16122051/

相关文章:

c# - 为什么不允许在 .NET 中就地实现接口(interface)?

java - 我如何实现文件扫描器的多线程场景?

multithreading - Rayon 会避免为少量工作生成线程吗?

java - 如何在java中的线程之间传递整数/其他变量?

c# - 更改 EDMX 中所有表的架构名称

c# - Internet Explorer 缓存从数据库返回的数据

c# - 将 Action<T> 回调转换为等待

c# - 我应该如何加密 Azure WebJob 的 App.config?

python - Python 3 中的 XMPP 线程接收器

c# - 开始,停止,暂停和继续运行很长时间的方法