I noticed that sometimes my code becomes out of sync if an event fires too quickly. I was wondering if there was a better approach. Under a normal scenario the DeviceOpenedEvent fires after I tell the thread to WaitOne in the TestDevice method, but I have seen in some cases where the event gets fired before the thread has a chance to wait.
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();
}
Under normal circumstances it looks like this:
- Open Device
- WaitOne()
- DeviceOpenedEvent occurs
- Set()
This is what I’m seeing my logs sometimes:
- Open Device
- DeviceOpenedEvent occurs
- WaitOne() Essentially stuck here forever
Since
OpenDeviceis asynchronous (as you mentioned in a comment), it runs in a different thread than its caller. Sometimes it will finish before the next line in source executes:When that happens
DeviceOpenedEventdoesn’t do what you want it to, becauseWaitForEventis stillEventEnum.None:The solution is to change your code so that you signal completion inside a method that’s guaranteed to run in the correct order. Here’s a simple implementation that removes the enumeration and uses a single wait handle for each event you need to wait on:
It’s even easier if you control
OpenDevice: just calldeviceOpened.Set()when it’s done. You could even changeOpenDeviceto accept the auto reset event and construct it right insideTestDevice, which would reduce your exposure to multithreading bugs.