AutoResetEvent和COM对象

时间:2009-09-28 23:31:05

标签: c# com multithreading message-loop

我注意到AutoResetEvent在WaitOne()调用过程中完全冻结了消息循环(有时),甚至有效地阻止了信号消息。

IE:

  1. (UI)新线程产生
  2. (UI)代码调用WaitOne();超时:10秒
  3. (T2)线程打开设备,调用Set()
  4. (UI)WaitOne阻止消息循环
  5. (UI)WaitOne超时,代码执行继续
  6. (UI)主窗口接收信号并继续(但WaitOne失败)
  7. 有什么想法吗?

    编辑:添加UI / T2以指定线程。此外,我正在尝试将第三方库转为同步。打开设备涉及一个Open()调用,该调用又生成OpenOK或OpenFailed事件,我正在尝试进行bool Open()调用,该调用返回true / false,具体取决于生成的事件。

3 个答案:

答案 0 :(得分:1)

  

...有效地甚至阻止信号消息。

您不能“阻止信号”被发送,您只能阻止其他线程到达设置事件的点。等待句柄根本不需要消息泵。

我唯一能想到的可能是有问题的COM对象与UI线程相关联。访问COM对象可能正在尝试从T2调用回到正在等待T2做某事的UI线程(死锁)。要确定这是否确实存在问题,请确保您没有在UI线程上创建或访问COM对象。

答案 1 :(得分:0)

这是竞争条件的结果。问题是步骤3可能在步骤2之前发生,因为它们位于不同的线程上。因为您正在使用AutoResetEvent,所以在调用WaitOne时,事件已经重置。

由于这个问题,我通常尽量避免使用AutoResetEvents来支持ManualResetEvents。

使用ManualResetEvent的事件顺序是(我已将事件2列为2a和2b,以证明其操作顺序无法保证):

  1. New Thread Spawned
  2. 一个。原始线程调用WaitOne();湾新线程调用Set();
  3. 原始线程醒来。
  4. 原始线程调用Reset();

答案 2 :(得分:0)

您可能会发现this SO帖子“在继续处理时等待主线程”
还可以从MSDN结帐Calling Synchronous Methods Asynchronously