4

あらすじ:

非スレッドアプリケーションをスレッドアプリケーションに変換しようとしています。私は約10年間、アプリケーションでスレッドを使用しておらず、その概念に非常に錆びています。私が把握していないことがあります。私の(非常に短い)コードの前後を見て、私が間違っていることと、なぜそれが間違っているのかを確認してください。すべての助けは大歓迎です!ありがとう!

見られるエラー:

コードが応答していません。ボタンを実行して実行し、アプリケーションを起動できますが、新しいスレッドを開始して動作するのではなく、ボタンがフリーズして「応答していません」というメッセージが表示されます。何を間違えたのかわかりません。スレッドを正しく実装しませんでしたか?

非スレッドコード:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
    //userform UserForm = new userform();
    //UserForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

壊れたスレッドコード:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(enumerationStuff);
    bg.RunWorkerAsync();

}
//run enumeration application in new thread
private void enumerationStuff(object sender, DoWorkEventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(correlationStuff);
    bg.RunWorkerAsync();
}
//run correlation application in new thread
private void correlationStuff(object sender, DoWorkEventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}
4

3 に答える 3

4

BackgroundWorkersは、まさにそれを実行するように設計されています-バックグラウンドで作業します。これらは、新しいウィンドウを表示したり、UI自体を表示したりするようには設計されていません。これは、定義上、フォアグラウンド作業です。BackgroundWorkersはメッセージを処理しないため、マウスクリックやキーボード入力などにまったく応答しません。そのため、ウィンドウには「応答なし」と表示されます。

あなたがここで実際に何を達成しようとしているのかはっきりしていないので、この質問に答えるのは難しいです。最初の非スレッドコードの何が問題になっていますか?

「個々のアプリケーション」(実際には単なるフォーム)がアプリケーション全体をフリーズしている場合、それらはおそらくUIスレッドで非常に多くの作業を行っています。その場合、BackgroundWorkersが解決策になる可能性がありますが、間違った場所で使用しています。「たくさんの仕事」をしているコード(どんな仕事でも)を見つけて、そのコード(そしてそのコードだけ)をBackgroundWorkerに入れることができるかどうかを確認してください。ただし、実行できないのは、BackgroundWorker内からUIを使用して何かを実行することです。つまり、UIスレッドは1つ(開始したスレッド)しかなく、そのスレッドだけがUIにアクセスできます。

于 2012-08-01T13:15:37.057 に答える
2

.NET / Windowsユーザーインターフェイスでは、単一のユーザーインターフェイススレッドからUI操作を実行することはできません。一言で言えば、UI自体はシングルスレッドですが、UIに触れない長時間実行される操作は、セカンダリ/バックグラウンドスレッドで問題なく発生する可能性があります。

これがControl.Invoke、UIスレッドコンテキストで特定のコードの実行を要求できるようにするための存在のようなものである理由です。

于 2012-08-01T13:15:51.170 に答える
2

ここでの主な問題は、バックグラウンドスレッドでGUIコンポーネントを作成して実行しようとすることです。ユーザーに入力を求める必要があるとすると、このコードを別のスレッドに生成する理由がわかりません。

UIスレッドでフォームを起動したままにして、代わりにそれらのフォームが行う余分な作業をバックグラウンドスレッドに渡します。

于 2012-08-01T13:16:14.873 に答える