C#.NET アプリケーションのスレッド間の通信で問題に直面しています。誰かが可能な解決策について正しい方向に導いてくれることを願っています。
私は C#.NET でアプリケーションを持っています。これは Windows フォーム アプリケーションです。私のアプリケーションには 2 つのスレッドがあります。1 つのスレッドはメイン スレッド (UI スレッド) で、もう 1 つは子スレッドです。子スレッドを「workerThread」と呼びましょう アプリケーションで使用されるフォームは 1 つだけです。このフォームを「MainForm」と呼びましょう
MainForm が読み込まれると、子スレッドが開始されます (フォームの「Load」イベント ハンドラを使用してスレッドを開始します)。
MainForm クラスには、パブリック ブール変数である「stopWork」という名前の変数があり、子スレッドが引き続き動作するか停止するかを示すフラグとして機能します。
子スレッドで実行するメソッドを含む別のクラス (MainForm クラス以外) があります。この 2 番目のクラスを「WorkerClass」と呼びましょう。現在のフォーム (MainForm) への参照を「WorkerClass」のコンストラクターに渡します。
メインフォームに「停止」ボタンがあり、クリックすると「stopWork」を「true」に設定し、「workerThread.Join()」を呼び出して子スレッドが実行を終了するのを待ちます。
子スレッドでは、メソッド「doWork」がforループ内の「parentForm.stopWork」のステータスをチェックし続けます。「stopWork」が「true」に設定されている場合、ループが中断され、その後メソッドが終了します。
さて、問題は、「停止」ボタンをクリックすると、アプリケーションがハングすることです。
理解しやすいように、以下のコードの一部を貼り付けています。
public partial class MainForm : Form
{
Thread workerThread = null;
ThreadStart workerThreadStart = null;
WorkerClass workerClass = null;
public bool stopWork = true;
/*.......... some code ............*/
private void MainForm_Load(object sender, EventArgs e)
{
workerThreadStart = new ThreadStart(startWork);
workerThread = new Thread(workerThreadStart);
stopWork = false;
workerThread.Start();
}
private void startWork()
{
workerClass = new WorkerClass(this);
}
private void buttonStop_Click(object sender, EventArgs e) //"stop" button
{
if (workerThread != null)
{
if (workerThread.IsAlive == true)
{
stopWork = true;
workerThread.Join();
}
}
}
/*.......... some more code ............*/
}
public class WorkerClass
{
MainForm parentForm=null;
/*......... some variables and code ........*/
public WorkerClass(MainForm parentForm)
{
this.parentForm=parentForm;
}
/* .............. some more code ...........*/
public void doWork()
{
/*.......... some variables and code ...........*/
for(int i=0;i<100000;i++)
{
// ** Here is the check to see if parentForm has set stopWork to true **
if(parentForm.stopWork==true)
break;
/*......... do some work in the loop ..........*/
}
}
/********* and more code .........*/
}
問題がどこにあるかを知ることができると思います。問題は、「workerThread.Join()」メソッドを呼び出して親フォームが既にブロックされているときに、親フォームの「stopWork」変数にアクセスしようとする子スレッドの「doWork」メソッドにあります。したがって、これは「デッドロック」の問題だと思います。
問題を特定するのは正しいですか?それとも私が間違っていて、問題は別の場所にありますか?
これが実際にデッドロックである場合、これを解決するための可能な解決策は何ですか?
少しグーグルで調べたところ、スレッドの同期とデッドロックを回避する方法に関する多くのリソースが見つかりました。しかし、私の問題に具体的に適用する方法がわかりませんでした。
この問題を解決するためのヘルプやガイダンスをいただければ幸いです。