gpt4 book ai didi

c# - 同步事件

转载 作者:行者123 更新时间:2023-11-30 16:29:29 24 4
gpt4 key购买 nike

我注意到如果事件触发得太快,有时我的代码会变得不同步。我想知道是否有更好的方法。在正常情况下,我在 TestDevice 方法中告诉线程 WaitOne 后 DeviceOpenedEvent 会触发,但我看到在某些情况下,事件在线程有机会等待之前被触发。

    protected AutoResetEvent TestAutoResetEvent = new AutoResetEvent(false);
public EventEnum WaitForEvent = EventEnum.None;

bool TestDevice()
{
OpenDevice();

WaitForEvent = EventEnum.DeviceOpened;
TestAutoResetEvent.WaitOne();
WaitForEvent = EventEnum.NoWait;

//Continue with other tests
}

void DeviceOpenedEvent()
{
if (WaitForEvent == EventEnum.DeviceOpened)
TestAutoResetEvent.Set();
}

正常情况下是这样的:

  1. 打开设备
  2. 等待一次()
  3. DeviceOpenedEvent 发生
  4. 设置()

这就是我有时看到的日志:

  1. 打开设备
  2. DeviceOpenedEvent 发生
  3. WaitOne() 基本上永远卡在这里

最佳答案

由于 OpenDevice 是异步的(正如您在评论中提到的),它在与其调用者不同的线程中运行。有时它会在源代码中的下一行执行之前完成:

    OpenDevice(); // Async: may finish before the next line executes!
WaitForEvent = EventEnum.DeviceOpened;

发生这种情况时,DeviceOpenedEvent 不会执行您想要的操作,因为 WaitForEvent 仍然是 EventEnum.None:

if (WaitForEvent == EventEnum.DeviceOpened)         
TestAutoResetEvent.Set();

解决方案是更改您的代码,以便在保证以正确顺序运行的方法中发出完成信号。这是一个简单的实现,它删除了枚举并为您需要等待的每个事件使用一个等待句柄:

protected AutoResetEvent deviceOpenedEvent = new AutoResetEvent(false);
protected AutoResetEvent deviceLockedEvent = new AutoResetEvent(false);

bool TestDevice() {
OpenDevice();
// Do some unrelated parallel stuff here ... then
deviceOpenedEvent.WaitOne();
LockDevice();
deviceLockedEvent.WaitOne();
}

void DeviceOpenedEvent() {
deviceOpenedEvent.Set();
}

如果您控制 OpenDevice,那就更容易了:完成后只需调用 deviceOpened.Set()。您甚至可以更改 OpenDevice 以接受自动重置事件并在 TestDevice 中构建它,这将减少您暴露于多线程错误的可能性。

关于c# - 同步事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6296334/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com