DocumentViewer
和其他控件。当这个窗口被打开并加载时,它会动态地构建一个带有进度指示器的FixedDocument
,然后在DocumentViewer
中显示它。为了改善用户体验,我将该窗口运行在它自己的线程中,以便在构建文档时主应用程序窗口仍然响应。根据此网页上的提示,我像这样在新线程中打开我的窗口:public void ShowDocumentViewerWindow(params object[] data) {
var thread = new Thread(() => {
var window = new MyDocumentViewerWindow(new MyObject(data));
window.Closed += (s, a) => window.Dispatcher.InvokeShutdown();
window.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
到目前为止,我对这个设置非常满意,但是我遇到了一个问题。
MyDocumentViewerWindow
包含一个打印按钮,该按钮引用内置的打印命令,目标是文档查看器:
<Button Command="Print" CommandTarget="{Binding ElementName=MyDocumentViewer}">Print</Button>
在将窗口放到自己的线程之前,这段代码可以正常工作。但是现在当我点击它时,应用程序会崩溃。Visual Studio 2010 将上面代码中的以下行标记为崩溃位置,并显示 'The calling thread cannot access this object because a different thread owns it.' 的信息:
System.Windows.Threading.Dispatcher.Run();
堆栈跟踪从这里开始:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at MS.Internal.Printing.Win32PrintDialog.ShowDialog()
at System.Windows.Controls.PrintDialog.ShowDialog()
at System.Printing.PrintQueue.GatherDataFromPrintDialog(PrintDialog printDialog, XpsDocumentWriter&amp; writer, PrintTicket&amp; partialTrustPrintTicket, PrintQueue&amp; partialTrustPrintQueue, Double&amp; width, Double&amp; height, String jobDescription)
at System.Printing.PrintQueue.CreateXpsDocumentWriter(String jobDescription, PrintDocumentImageableArea&amp; documentImageableArea)
at System.Windows.Controls.Primitives.DocumentViewerBase.OnPrintCommand()
at System.Windows.Controls.Primitives.DocumentViewerBase.ExecutedRoutedEventHandler(Object target, ExecutedRoutedEventArgs args)
...
我猜测打印对话框是在主UI线程打开的,并且试图访问由我的线程创建和拥有的文档,因此导致了崩溃。
有什么想法可以解决这个问题吗?我想保持窗口在其自己的线程中。