【问题标题】:Waiting for event to fire on a main thread from a background thread spawned by it等待事件从由它产生的后台线程在主线程上触发
【发布时间】:2014-01-06 03:48:05
【问题描述】:

我有一种情况,我正在处理最初从事件触发的线程中的一些数据,但它需要等到主线程中发生某些事情才能继续 - 问题可能是这些数据中的任意数量正在运行同时。真正的基本示例:

事件触发 -> 方法设置为在自己的线程上在后台运行 -> 使用主线程的发送数据方法发送数据 -> 等待接收该数据的 ACK -> 在主线程上设置 WaitHandle - > 工作线程将发送下一组数据 -> 重复 -> 当所有数据都已发送并确认后退出线程。

目前我有一个 AutoResetEvent 每次收到 ACK 时都会设置 - 并且正在运行的工作线程会监听它 - 但如果碰巧有 10 个工作线程同时运行,并且它们都在监听对它来说——它违背了目的。

我需要生成工作线程,并让它侦听 (WaitOne) 以设置/重置特定的 WaitHandle,并仅以此为基础继续。

完成这样的事情的最佳方法是什么?以某种方式创建一个 WaitHandles 数组并让工作线程侦听其索引的 AutoResetEvent?

【问题讨论】:

  • “以某种方式创建一个 WaitHandles 数组并让工作线程监听其索引的 AutoResetEvent?” - 是的 :-)

标签: c# multithreading waithandle


【解决方案1】:

我不确定您的线程和其他进程交互的确切方式,但我之前使用的模式是字典,其中手动或自动重置事件是值,并且您设置了某种ID 作为键,例如事件、事件发送者、用户 ID 等等。

这样您就可以在字典中搜索相关 ID(使用默认索引器),然后等待句柄。如果您需要将等待句柄异步添加到列表中(例如,在引发事件时),您可能需要使用 ConcurrentDictionary 类。我不确定您需要什么,但如果您需要等待所有事件都完成后再完成某些操作,您也可以查看队列。

注意跨线程同步。您不想在 GUI 应用程序上阻塞主线程,并且不能从同​​一线程编辑 GUI

【讨论】:

  • ConcurrentDictionary 非常适合这个应用程序。每次客户端进入需要确认消息的模式时,我都对其进行了 TryAdd (ConcurrentDictionary()),然后在每个消息进入时为该特定客户端设置它 - 在工作人员中线程我只是在等待那个键的 WaitHandle。很好的解决方案!
【解决方案2】:

我认为您在抽象中挖掘的层次有点太低了。您是否有理由不能使用带有一两个队列的更典型的生产者-消费者模型来处理正在进行的请求和响应?当您不尝试重新创建低级同步原语时,将其正确化会容易得多。

【讨论】:

  • 通常我会让每个客户端连接到它自己的侦听器(TCP/IP 套接字)线程,并简单地在该特定客户端的侦听器中注册事件。在这种情况下,我在单个线程上为所有客户端使用异步服务器/侦听器 - 因此没有一种很好的方法可以将侦听器中的单个事件绑定到特定客户端。我猜这听起来很混乱,但现在这整件事让我很困惑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多