如果在OnRender()中直接显示MessageBox时,会出现这个异常错误:the exception message is "Dispatcher processing has been suspended, but messages are still being processed.".
所以,在这里我采用BeginInvoke()实现这个功能。
protected override void OnRender(DrawingContext drawingContext)
{
……
System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new ShowErrorMessageEvent(ShowErrorMessage));
}
private delegate void ShowErrorMessageEvent();
private void ShowErrorMessage()
{
MessageBox.Show("Error string!");
}
下面是msdn关于Dispatcher和BeginInvoke的介绍:
Dispatcher 可为特定线程维护其按优先顺序排列的工作项队列。
当在线程中创建了 Dispatcher 时,它将成为可与该线程关联的唯一 Dispatcher,即使 Dispatcher 已经关闭。
如果尝试获取当前线程的 CurrentDispatcher,而此时该线程没有关联的 Dispatcher,则将创建一个 Dispatcher。
如果 Dispatcher 已经关闭,它将无法重新启动。
在 WPF 中,DispatcherObject 只能通过与它关联的 Dispatcher 进行访问。例如,后台线程不能更新与 UI 线程中的 Dispatcher 关联的 Button 内容。为了使该后台线程能够访问 Button 的 Content 属性,该后台线程必须将此工作委托给与该 UI 线程关联的 Dispatcher。这可以通过使用 Invoke 或 BeginInvoke 来完成。
Invoke 是同步操作,而 BeginInvoke 是异步操作。该操作将按指定的 DispatcherPriority 添加到 Dispatcher 的事件队列中。 BeginInvoke 是异步操作;因此,调用之后控制权会立即返回给调用对象。
BeginInvoke 返回一个 DispatcherOperation 对象,当委托位于事件队列中时,该对象可用于与委托进行交互。
如果按同一个 DispatcherPriority 调用多个 BeginInvoke,将按调用发生的顺序执行它们。
如果对某个已关闭的 Dispatcher 调用 BeginInvoke,则返回的 DispatcherOperation 的状态属性将设置为 Aborted。