C# Class Bloom.ToPalaso.SafeInvoke

Show file Open project: BloomBooks/BloomDesktop

Public Methods

Method Description
Invoke ( string nameForErrorReporting, Control control, bool forceSynchronous, bool throwIfAnythingGoesWrong, System.Action action ) : void

Invoke and action safely even if called from the background thread.

Invoking on the ui thread from background threads works *most* of the time, with occasional crash. Stackoverflow has a good collection of people trying to deal with these corner cases, where InvokeRequired(), for example, is unreliable (it doesn't tell you if the control hasn't even got a handle yet). SIL.Core (lipalaso) has a SafeInvoke on its LogBox control, which sees heavy background/foreground interaction and seems to work well over the course of years. I think I (JH) wrote that, but it relies on a couple of odd things: 1) it calls IsHandleCreated() (which can reportedly create the handle on the wrong thread?) and 2) uses SynchronizationContext which works for that single control case but I'm not seeing how to generalize that. So now I'm trying something more mainstream here, from a highly voted SO answer.

InvokeIfPossible ( string nameForErrorReporting, Control control, bool forceSynchronous, System.Action action ) : void

This version just makes it clear that the call is permissive, won't bother the user if something goes wrong, which is appropriate for many background-->foreground ui tasks, like refreshing.

Method Details

Invoke() public static method

Invoke and action safely even if called from the background thread.
Invoking on the ui thread from background threads works *most* of the time, with occasional crash. Stackoverflow has a good collection of people trying to deal with these corner cases, where InvokeRequired(), for example, is unreliable (it doesn't tell you if the control hasn't even got a handle yet). SIL.Core (lipalaso) has a SafeInvoke on its LogBox control, which sees heavy background/foreground interaction and seems to work well over the course of years. I think I (JH) wrote that, but it relies on a couple of odd things: 1) it calls IsHandleCreated() (which can reportedly create the handle on the wrong thread?) and 2) uses SynchronizationContext which works for that single control case but I'm not seeing how to generalize that. So now I'm trying something more mainstream here, from a highly voted SO answer.
public static Invoke ( string nameForErrorReporting, Control control, bool forceSynchronous, bool throwIfAnythingGoesWrong, System.Action action ) : void
nameForErrorReporting string
control System.Windows.Forms.Control
forceSynchronous bool
throwIfAnythingGoesWrong bool
action System.Action
return void

InvokeIfPossible() public static method

This version just makes it clear that the call is permissive, won't bother the user if something goes wrong, which is appropriate for many background-->foreground ui tasks, like refreshing.
public static InvokeIfPossible ( string nameForErrorReporting, Control control, bool forceSynchronous, System.Action action ) : void
nameForErrorReporting string
control System.Windows.Forms.Control
forceSynchronous bool
action System.Action
return void