NonSoft

スレッドの開始/終了と同期(排他制御)
のサンプル(C#.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
スレッドを生成して開始/終了や一時停止/再開するサンプル(C#.NET)です。
2つのスレッドを開始して同期(排他制御)して動くようにしています。
排他制御にはSyncLock(C#ではlock)を使用しています。

このサンプルではスレッド処理として「デバッグ分を1秒毎に3回表示」する処理を繰り返す
ようにしています。

排他制御のSyncLock(C#ではlock)部分を削除すると、スレッド1とスレッド2のデバッグ分が
混ざって表示されますが、排他制御のSyncLock(C#ではlock)があるとスレッド1の処理が完了
した後にスレッド2の処理が開始されます。

また、このサンプルの一時停止/再開にはSuspend()とResume()を使用しています。
Suspend()とResume()は過去(旧形式)のメソッドで.NetFramework2.0では互換性のために
残っていますが、今後の.NetFrameworkのリリースで削除されるようです。

VB.NET版はこちらです。スレッドの開始/終了と同期(排他制御)のサンプル(VB.NET)

CPUにデュアルやクアッドのコアを使用していても、スレッド対応していないアプリはその恩恵を
最大限に受ける事は出来ません。出来るだけスレッド対応するように心がけたいものです。

★フォーム・クラス(Form1.cs)
public partial class Form1 : Form
{
    private System.Threading.Thread thread1;
    private System.Threading.Thread thread2;
    private object syncobj = new object();

    // スレッド開始ボタン
    private void button1_Click(object sender, EventArgs e)
    {
        // スレッド作成
        thread1 = new System.Threading.Thread(Thread_Proc1);
        thread2 = new System.Threading.Thread(Thread_Proc2);

        // スレッド開始
        thread1.Start();
        thread2.Start();
    }

    // スレッド終了ボタン
    private void button2_Click(object sender, EventArgs e)
    {
        // スレッド終了
        thread1.Abort();
        thread2.Abort();
    }

    // スレッド停止ボタン
    private void button3_Click(object sender, EventArgs e)
    {
        // スレッド停止
        thread1.Suspend();  // 旧形式(今後のリリースで削除されます)
        thread2.Suspend();  // 旧形式(今後のリリースで削除されます)
    }

    // スレッド再開ボタン
    private void button4_Click(object sender, EventArgs e)
    {
        // スレッド再開
        thread1.Resume();   // 旧形式(今後のリリースで削除されます)
        thread2.Resume();   // 旧形式(今後のリリースで削除されます)
    }

    // フォームクローズ
    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // スレッド終了
        thread1.Abort();
        thread2.Abort();
    }

    // スレッド関数
    private void Thread_Proc1(){
        System.Diagnostics.Debug.WriteLine(" Thread1開始");
        try{
            while (true)
            {
                lock (syncobj)  // 同期(排他制御)
                {
                    System.Diagnostics.Debug.WriteLine(
                        " Thread1-1:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);

                    System.Diagnostics.Debug.WriteLine(
                        " Thread1-2:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);

                    System.Diagnostics.Debug.WriteLine(
                        " Thread1-3:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);
                }
            }
        }catch( System.Threading.ThreadAbortException){
            return;
        }
        finally
        {
            System.Diagnostics.Debug.WriteLine(" Thread1終了");
        }
    }

    // スレッド関数
    private void Thread_Proc2()
    {
        System.Diagnostics.Debug.WriteLine(" Thread2開始");
        try
        {
            while (true)
            {
                lock (syncobj)  // 同期(排他制御)
                {
                    System.Diagnostics.Debug.WriteLine(
                        "*Thread2-1:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);

                    System.Diagnostics.Debug.WriteLine(
                        "*Thread2-2:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);

                    System.Diagnostics.Debug.WriteLine(
                        "*Thread2-3:" + DateTime.Now.ToString());
                    System.Threading.Thread.Sleep(1000);
                }
            }
        }
        catch (System.Threading.ThreadAbortException)
        {
            return;
        }
        finally
        {
            System.Diagnostics.Debug.WriteLine(" Thread2終了");
        }
    }
}