私は、いくつかのWindowクラスを含み、それらのウィンドウを表示するメソッドを公開するWPF dllを持っています。WinForms BackgroundWorkerからWPFウィンドウを作成する
また、WPFプロジェクトでBackgroundWorkerコンポーネントのDoWorkメソッド内でこれらのメソッドの1つを呼び出す別のWinFormsプロジェクトもあります。 WPFウィンドウをインスタンス化するコードの行で
、私は、次のランタイムエラーを取得:
The calling thread must be STA, because many UI components require this.
Google検索がthis discussionにさせて頂いております。 (ジョンスキートはスタックオーバーフローに加えて、他のサイト上の質問に答えが判明!)彼は、記事はまた、DispatcherObjectにクラスを使用して言及しているが、私はことを確認する方法を理解していない
The BackgroundWorker component works well with WPF ...
を述べている、this articleにリンク私はBackgroundWorkerコンポーネントを使用し続けます。
テストケースとして、私はエラーを再現するために次のコードを考え出しました。 WPFのクラスライブラリに、ここでのコードは、ここでコードはBackgroundWorkerのコンポーネントが配置されている場合でも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
であり、リサイズアプリケーションで
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
Window1.xaml.vb
でありますWindow1.xaml.vb自体で同じエラーが発生します。だから、その記事は間違っていて、私は実際にWPFでBackgroundWorkerを使用することはできませんか?それとも、それを働かせるために何か必要なことはありますか?BackgroundWorkerが機能しない場合は、上記のForm1.vbのコードを代わりに使用してDispatcherを使用する方法はありますか。
ありがとう! DoWorkイベントのコードをRunWorkerCompletedイベントにコピーしただけで動作します。 – CoderDennis
FYI、RunWorkerCompletedはワーカーのスレッドではなくワーカーを開始したのと同じスレッドで実行されると思います。もしそうなら、あなたはBackgroundWorkerをまったく使用しないかもしれません。 –
あなたはWPFで複数のUIスレッドを持つことができます(私がやったことがあります)。しかし、あなたのコントロール下にないので、BackgroundWorkerスレッドからUIを表示することは望ましくありません.ToolPoolはそのスレッドが何をいつ実行するかを決定します。通常のスレッドが必要で、STAに設定し、ThreadStartメソッドからApplication.Runを呼び出します。 –