I have a background task that sits in a loop reading data from an external hardware device. The device exposes a "counter" that increments every 100ms - when this value changes I fetch the next data value from the device and raise an event. Psuedo-code:-
public event HasDataEventArgs DataReceived;
while (some condition)
{
// Wait for device counter to increment
while (DeviceCounterValue == _lastDeviceCounterValue)
{
Thread.Sleep(3);
}
_lastDeviceCounterValue = DeviceCounterValue;
// Read data value from device
var data = GetDataFromDevice();
// Raise my event
DataReceived(this, new HasDataEventArgs(data));
}
I also have a UI view that subscribes to this event. The event handler plots the data value on a chart and sets a number of bound properties.
Most of the time this all works fine, but if I (say) drag a window around or open a modal dialog, it can occasionally result in data being missed. What seems to happen is that the external device counter carries on incrementing, but the 'while' loop has effectively stalled briefly, so misses those changes. Very occasionally I'll see the same effect even when I'm not messing around with anything in the UI.
The event handler in the view isn't doing much, but this is a complex desktop application with other background threads updating other bound controls. Perhaps this particular process is just tipping things over the edge performance-wise, especially once I start dragging windows around?
I was wondering if I could wrap the event handler code in a Task.Run()
, which (I assume) would result in it returning control to the while loop immediately, rather than have to wait for the event handler to do its thing. It sounds hacky though - am I asking for trouble with something like this, especially given the frequency that the event handler will be called (every 100ms)?