BackgroundWorkerイベントが発生しないことについて混乱
-
04-07-2019 - |
質問
これはやや不自然な例のように思えるかもしれませんが、頭をかきむしっています。
OK、WindowsFormをインスタンス化し、フォームでDoSomeWork()と呼ばれるメソッドを呼び出すコンソールアプリがあります。
class Program
{
static void Main(string[] args)
{
Form1 form = new Form1();
form.DoSomeWork();
}
}
Form1は次のようになります...
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void DoSomeWork()
{
OuterClass outerClass = new OuterClass();
outerClass.DoSomeWork();
}
}
外部クラスは、次のようになります...
public class OuterClass
{
public void DoSomeWork()
{
InnerClass innerClass = new InnerClass();
innerClass.DoSomeWork();
}
}
最後に、InnerClassは次のようになります...
public class InnerClass
{
private BackgroundWorker _backgroundWorker = new BackgroundWorker();
public InnerClass()
{
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
}
void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int i = 0; //I've placed a break point here. But it's never hit
}
void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
worker.ReportProgress(42);
}
public void DoSomeWork()
{
_backgroundWorker.RunWorkerAsync();
}
}
(私には)不明な理由で、InnerClassのBacgroundWorkerは ProgressChanged イベントを発生させないようです。交換する場合
Form1 form = new Form1();
with
OuterClass outerClass = new OuterClass()
クラスProgramでは、正常に動作します。それでは、フォームを介して同じメソッドを呼び出しているときに、イベントが発生しないのはなぜですか?
ありがとう!
編集:ProgressChangedイベントハンドラーからNotImplementedExceptionをスローするようにして、人々を追い払うように見えたので、明確にするために削除しました。
解決
メッセージループの開始を忘れたため、Application.Run()を呼び出す必要があります。メッセージループがなければ、BackgroundWorkerイベントは機能しません。修正するには:
static void Main(string[] args)
{
Application.Run(new Form1());
}
フォームのコンストラクターまたはそれのLoadイベントでDoSomeWork()を呼び出します。
他のヒント
ハンドラーで実際に NotImplementedException();
をスローしましたか?それとも、これをすばやくモックアップして削除するのを忘れただけですか?
利用されているさまざまなスレッドアパートメントモデルに関連していると思います。
私の経験から、シングルスレッドアパートメント非UI スレッドがメインUIスレッドの外で例外をスローした場合、そのスレッドは警告なしに単純に終了します。
Windows Formsでは、正しく覚えていればコンソールアプリケーションとは異なるアパートメントモデルが必要です。それが問題の原因かもしれません。
間違っている可能性がありますが、それはいくつかの指針を与えるはずです。