【发布时间】:2015-07-30 00:14:38
【问题描述】:
我最初尝试使用 Dispatcher 类 BeginInvoke 方法在我的 C# Windows 窗体应用程序的主 UI 线程上显示一个消息框。当我使用该方法时,消息框没有出现。我在传递给 BeginInvoke() 的委托主体内设置了一个断点,它从未命中。我尝试同时使用 Action 委托和 MethodInvoker 委托。两种情况都没有运气。
当我使用属于 Form 对象的 BeginInvoke 方法时,它运行良好。为什么 Dispatch 版本会静默失败(没有异常或错误消息)?以下是两个不同的版本。
Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
// THIS FAILED. CONTEXT: Executing on worker thread.
MethodInvoker theMethod = new MethodInvoker(delegate()
{
string msg = "Show this message on the main UI thread.";
MessageBox.Show(msg, "Message");
});
dispatcher.BeginInvoke(theMethod);
this.BeginInvoke(theMethod);
// ---------------------------------------------------
// THIS WORKED. CONTEXT: Executing on worker thread.
MethodInvoker theMethod = new MethodInvoker(delegate()
{
string msg = "Show this message on the main UI thread.";
MessageBox.Show(msg, "Message");
});
// "this" is a Form object.
this.BeginInvoke(theMethod);
【问题讨论】:
-
似乎此页面包含如何将
Dispatcher与winforms 一起使用的示例:stackoverflow.com/questions/303116/… -
我尝试了你的
dispatcher.BeginInvoke(...);代码,它在 .NET4 中运行良好。 -
@Loathing 感谢您的测试。我(不止)在测试期间进行了三次检查,我可以向你保证,对我来说它绝对没有用。所以现在我们显然遇到了一个非常奇怪的情况。
-
@RobertOschler:这里已经有一个很好的答案,但作为旁注:您不应该使用任何
BeginInvoke方法。要报告进度,请使用IProgress<T>。要使用结果更新 UI,请使用await。要从异步流动态更新 UI,请使用 Rx 的ObserveOn(SynchronizationContext)。这些较新的方法将您的逻辑与您的 UI 分离,并且可以进行单元测试。 -
@StephenCleary 谢谢斯蒂芬。
标签: c# winforms dispatcher begininvoke