Печать содержимого DocumentViewer в другом потоке UI

В моем WPF-приложении есть определенное Window, которое содержит, среди прочих элементов управления, 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 содержит кнопку печати, которая ссылается на встроенную команду Print, предназначенную для DocumentViewer:


До того, как у меня было окно в собственном потоке, это работало нормально. Но теперь, когда я нажимаю на нее, приложение аварийно завершает работу. Visual Studio 2010 выделяет следующую строку из приведенного выше кода как место сбоя с сообщением 'Вызывающий поток не может получить доступ к этому объекту, потому что он принадлежит другому потоку. ":

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& writer, PrintTicket& partialTrustPrintTicket, PrintQueue& partialTrustPrintQueue, Double& width, Double& height, String jobDescription)
at System.Printing.PrintQueue.CreateXpsDocumentWriter(String jobDescription, PrintDocumentImageableArea& documentImageableArea)
at System.Windows.Controls.Primitives.DocumentViewerBase.OnPrintCommand()
at System.Windows.Controls.Primitives.DocumentViewerBase.ExecutedRoutedEventHandler(Object target, ExecutedRoutedEventArgs args)
...

Моя догадка заключается в том, что диалог печати открывается в основном потоке пользовательского интерфейса и пытается получить доступ к документу, который создан и принадлежит моему собственному потоку, отсюда и крах.

Есть идеи, как я могу решить эту проблему? Я бы хотел сохранить окно в собственном потоке.

5
задан Ross 7 September 2011 в 15:15
поделиться

0 ответов

Другие вопросы по тегам:

Похожие вопросы: