3

多数の Window クラスを含み、それらのウィンドウを表示するメソッドを公開する WPF dll があります。

また、BackgroundWorker コンポーネントの DoWork メソッド内で WPF プロジェクトのこれらのメソッドの 1 つを呼び出している別の WinForms プロジェクトもあります。

WPF ウィンドウをインスタンス化するコード行で、次のランタイム エラーが発生します。

多くの UI コンポーネントがこれを必要とするため、呼び出しスレッドは STA でなければなりません。

グーグル検索でこの議論ができました。(Jon Skeet は、Stack Overflow に加えて他のサイトの質問にも答えていることがわかりました!) 彼はこの記事にリンクし、次のように述べています。

BackgroundWorker コンポーネントは WPF とうまく連携します ...

その記事では、DispatcherObject クラスの使用についても言及していますが、それを機能させる方法がわからないので、BackgroundWorker コンポーネントを引き続き使用したいと考えています。

テストケースとして、エラーを再現するために次のコードを思いつきました。WPF クラス ライブラリの Window1.xaml.vb のコードは次のとおりです。

Partial Public Class Window1

    Public Shared Function ShowMe() As Boolean?
        Dim w = New Window1 'Error appears on this line.
        Return w.ShowDialog()
    End Function

End Class

WinForms アプリケーションの Form1.vb のコードは次のとおりです。

Imports System.ComponentModel

Public Class Form1

    Private WithEvents worker As BackgroundWorker
    Private Sub doWord(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles worker.DoWork
        WpfLibrary.Window1.ShowMe()
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        worker = New BackgroundWorker
        worker.RunWorkerAsync()
    End Sub
End Class

Window1.xaml.vb 自体に BackgroundWorker コンポーネントを配置しても同様のエラーが発生します。それで、その記事は間違っていて、WPF で BackgroundWorker を実際に使用することはできませんか? または、それを機能させるために他に何かする必要がありますか?

BackgroundWorker が機能しない場合、上記の Form1.vb のコードを置き換えて、代わりに Dispatcher を使用するにはどうすればよいでしょうか?

4

2 に答える 2

4

バックグラウンド ワーカーを WPF で使用できますが、それは問題ではありません。

あなたの問題は、winform または WPF アプリケーションのメイン UI スレッドの外部から UI を更新するタスクを実行できず、BackgroundWorker の DoWork メソッドが別のスレッドで実行されていることです。

したがって、BackgroundWorker を開始する前、またはその RunWorkerCompleted イベントで、BackgroundWorker のバックグラウンド スレッドの外で新しいウィンドウを開く必要があります。

ウィンドウを開くための呼び出しを囲むコードを知らなければ、これ以上アドバイスすることは困難ですが、正しい方向に向けられることを願っています。

于 2009-06-17T18:16:44.890 に答える