public static void Invoke(string nameForErrorReporting, Control control, bool forceSynchronous, bool throwIfAnythingGoesWrong, Action action)
{
Guard.AgainstNull(control, nameForErrorReporting); // throw this one regardless of the throwIfAnythingGoesWrong
//mostly following http://stackoverflow.com/a/809186/723299
try
{
if (control.IsDisposed)
{
throw new ObjectDisposedException("Control is already disposed. (" + nameForErrorReporting + ")");
}
if (control.InvokeRequired)
{
var delgate = (Action)delegate { Invoke(nameForErrorReporting, control, forceSynchronous, throwIfAnythingGoesWrong, action); };
if (forceSynchronous)
{
control.Invoke(delgate);
}
else
{
control.BeginInvoke(delgate);
}
}
else
{
// InvokeRequired will return false if the control isn't set up yet
if (!control.IsHandleCreated)
{
//This situation happened in BL-2918, prompting the introduction of this safeinvoke
throw new ApplicationException("SafeInvoke.Invoke apparently called before control created ("+ nameForErrorReporting+")");
//note, resist the temptation to work around this by just making the handle be created with something like
//var unused = control.Handle
//I've read a rumour that this can create the handle "on the wrong thread".
//At a minimum, we would need to investigate the truth of that before using it here.
}
action();
}
}
catch (Exception error)
{
if (throwIfAnythingGoesWrong)
throw;
else
{
Debug.Fail("This error would be swallowed in release version: " + error.Message);
SIL.Reporting.Logger.WriteEvent("**** "+error.Message);
}
}
}