I have some gauges in my application. Sometimes, when the UI is busy, my gauge thread stalls waiting to update some gauges. In that situation, I would like to simply abandon my plan and try updating the gauges on the next poll. I currently use the Control.Invoke to move from my data polling thread into the UI. I don't want to use BeginInvoke because I don't want to waste precious UI time updating gauges when it's only the final value that matters. Is there some other way to invoke code on the UI thread in a way that I can bail out early if I can't get on the UI thread in 40ms? Is the code in the Invoke method necessary, or is there some other way to invoke a method on the main thread?
There is no timeout option available. One option would be to use BeginInvoke
, but only if the previous message has been processed. This will require thread synchronization, but could be written similarly to:
// using
object syncObj = new object();
bool operationPending = false;
while (operation)
{
// ... Do work
// Update, but only if there isn't a pending update
lock(syncObj)
{
if (!operationPending)
{
operationPending = true;
control.BeginInvoke(new Action( () =>
{
// Update gauges
lock(syncObj)
operationPending = false;
}));
}
}
}
// Update at the end (since you're last update might have been skipped)
control.Invoke(new Action(UpdateGuagesCompleted));
While this wouldn't timeout, it would prevent you from "flooding" UI events onto the main thread, as only one operation would be processed at a time.
Edit: As Yaur mentioned, this approach can also be done without locking via Interlocked:
while (operation)
{
int pendingOperations = 0;
// ... Do work
// Update, but only if there isn't a pending update
if (0 == Interlocked.CompareExchange(ref pendingOperations, 1, 0))
{
control.BeginInvoke(new Action( () =>
{
// Update gauges
// Restore, so the next UI update can occur
Interlocked.Decrement(ref pendingOperations);
}));
}
}
// Update at the end (since you're last update might have been skipped)
control.Invoke(new Action(UpdateGuagesCompleted));