C# Dispatcher.Invoke挂起在WordAddin中

C# Dispatcher.Invoke挂起在WordAddin中,c#,wpf,dispatcher,C#,Wpf,Dispatcher,我已经编写了一个WordAddIn,允许用户为当前文档调用一些元数据。通过功能区中的自定义按钮,他们可以调用WPF。WPF调用实现如下: System.Windows.Application app = null; 然后在按钮调用的方法中: if (app == null) { app = new System.Windows.Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; app.

我已经编写了一个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对象将加载并显示,这也适用于以后的任何按钮单击。因此,似乎第一次调用调度程序时,它会挂起。如何防止这种情况发生?

由于这是同一个线程,我不确定您为什么要调度呼叫。当“当前”线程不是UI线程时,您只需要马歇尔调用UI线程,这不是您的情况-您只有一个线程

其次,Application.Run是一个阻塞方法,不应该在外接程序上下文中调用。无法在外接程序应用程序中创建WPF应用程序。顺便说一句,Application.Run始终在当前线程上运行,在您的情况下,这与加载项运行的同一个单词相同。应该是这样的


如果我理解正确,您创建WPF应用程序是因为您不想使用WinForms技术,而是WPF。在没有应用程序的情况下执行此操作。运行并不要发送呼叫,因为没有理由这样做。

我在Microsoft WPF论坛上获得了有关此操作的帮助。在一个新线程中创建和调用应用程序就可以做到这一点,因为应用程序确实会阻止调用它的当前线程

                    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(); }));                       
                    }

谢谢,我不知道。我想说的是,我确实看到了关于dispatcher.invoke的其他问题,但没有一个解决方案(添加优先级或使用.beginInvoke)对我有效。我现在发现word冻结的点是app.Run()时;被称为。它似乎接管了word和我的AddIn的当前实例的线程。下一个AddIn实例似乎很好,可以使用app来调度WPF。是否有将app.run分配给新线程的方法?我尝试了它,但发现一个错误,告诉我另一个线程已经“拥有”了应用程序。