Dispatcher.Invoke在WordAddin中挂起

时间:2014-02-12 00:14:03

标签: c# wpf dispatcher

我编写了一个WordAddIn,允许用户调用当前文档的某些元数据。通过功能区中的自定义按钮,他们可以调用WPF。 WPF调用实现如下:

        System.Windows.Application app = null;

然后在按钮调用的方法中:

if (app == null)
{
    app = new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
    app.Run();
}
MainWindow win = new MainWindow(graph);
app.Dispatcher.Invoke((Action)(() => { win.Show(); }));

Word启动后第一次单击该按钮时,没有任何反应,也无法编辑word文档中的内容。第二次单击该按钮时,WPF对象会加载并显示,这也适用于之后的任何按钮单击。因此,似乎第一次调度调度程序,它就会挂起。我该如何防止这种情况?

2 个答案:

答案 0 :(得分:2)

我不知道你为什么要分派这个电话,因为这是同一个线程。当“当前”线程不是UI线程时,您只需要对UI线程进行编组操作,这不是您的情况 - 您只有一个线程。

其次,Application.Run是一种阻塞方法,不应在加载项上下文中调用。您无法在加载项应用程序中创建WPF应用程序。顺便说一句,Application.Run总是在当前线程上运行,在你的情况下,运行相同的一个Word加载项。这应该如何。

如果我理解正确,那么您正在创建一个WPF应用程序,因为您不想使用WinForms技术而是使用WPF。如果没有Application.Run,​​请不要调度,因为没有理由这样做。

答案 1 :(得分:0)

我在Microsoft WPF论坛中得到了这方面的帮助。在新线程中创建和调用app可以解决这个问题,因为app确实阻止了它被调用的当前线程。

                    if (app == null)
                    {
                        Thread thread = new Thread(new ThreadStart(() =>
                            {
                                app = new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown };
                                autoResetEvent.Set();
                                app.Run();
                            }));
                        thread.SetApartmentState(ApartmentState.STA);
                        thread.Start();
                    }
                    else 
                    {
                        autoResetEvent.Set();
                    }
                    autoResetEvent.WaitOne(); //wait until app has been initialized on the other thread
                    app.Dispatcher.Invoke((Action)(() => { new MainWindow(graph).Show(); }));                       
                    }