我会让业务对象触发一个事件以被视图( UI )捕获并对该事件处理程序进行封送处理,因此您可以在那个地方Control
了解是否需要调用:
public static class ControlExtentions
{
public delegate void InvokeHandler();
public static bool SafeInvoke(this Control control, InvokeHandler handler)
{
if (control.InvokeRequired)
{
try
{
control.Invoke(handler);
}
finally { }
return false;
}
else
handler.Invoke();
return true;
}
}
如果您使用的是 WPF,您可以从 CaliburnMicro 获得灵感:
public static class Execute
{
private static Action<System.Action> executor = action => action();
/// <summary>
/// Initializes the framework using the current dispatcher.
/// </summary>
public static void InitializeWithDispatcher()
{
#if SILVERLIGHT
var dispatcher = Deployment.Current.Dispatcher;
executor = action => {
if(dispatcher.CheckAccess())
action();
else {
var waitHandle = new ManualResetEvent(false);
Exception exception = null;
dispatcher.BeginInvoke(() => {
try {
action();
}
catch(Exception ex) {
exception = ex;
}
waitHandle.Set();
});
waitHandle.WaitOne();
if(exception != null)
throw new TargetInvocationException("An error occurred while dispatching a call to the UI Thread", exception);
}
};
#else
var dispatcher = Dispatcher.CurrentDispatcher;
executor = action => {
if(dispatcher.CheckAccess())
action();
else dispatcher.Invoke(action);
};
#endif
}
/// <summary>
/// Resets the executor to use a non-dispatcher-based action executor.
/// </summary>
public static void ResetWithoutDispatcher() {
executor = action => action();
}
/// <summary>
/// Executes the action on the UI thread.
/// </summary>
/// <param name="action">The action to execute.</param>
public static void OnUIThread(this System.Action action) {
executor(action);
}
}