ホームページ  >  記事  >  バックエンド開発  >  C# WinForm マルチスレッド開発 (1) Thread クラスライブラリ

C# WinForm マルチスレッド開発 (1) Thread クラスライブラリ

黄舟
黄舟オリジナル
2017-02-20 10:56:321836ブラウズ

元のアドレス: クリックしてリンクを開きます

[概要]この記事では C# を紹介します WinForm マルチスレッド開発用の Thread クラス ライブラリ。参考用に簡単なサンプル コードを提供します。

Windows 2000 以降を使用している場合は、タスク マネージャーを通じてシステム上で現在実行されているプログラムとプロセスを表示できます。プロセスとは何ですか?プログラムが実行を開始すると、それはプロセスになります。プロセスとは、実行中のプログラムと、プログラムによって使用されるメモリおよびシステム リソースを指します。プロセスは複数のスレッドで構成されます。スレッドはプログラム内の実行フローです。各スレッドには独自のプライベート レジスタ (スタック ポインタ、プログラム カウンタなど) がありますが、コード領域は共有されます。つまり、異なるスレッドが実行できます。同じ機能です。マルチスレッドとは、プログラムに複数の実行ストリームが含まれていることを意味します。つまり、1 つのプログラム内で複数の異なるスレッドを同時に実行して、異なるタスクを実行できます。これは、1 つのプログラムで複数の並列実行スレッドを作成して、それぞれのタスクを完了できることを意味します。

1 Thread に関するメモ

.net Framework クラス ライブラリでは、マルチスレッド メカニズム アプリケーションに関連するすべてのクラスが System.Threading 名前空間に配置されます。これは、スレッドを作成するための Thread クラス、スレッド プールを管理するための ThreadPool クラスなどを提供します。さらに、スレッドの実行調整、デッドロック、スレッド間通信などの実際的な問題を解決するメカニズムも提供します。アプリケーションでマルチスレッドを使用する場合は、このクラスを含める必要があります。 Thread クラスには、次のようにいくつかの重要なメソッドがあります。

  • Start(): スレッドを開始します

  • Sleep(int): 静的メソッド、現在のスレッドを指定されたミリ秒間一時停止します

  • Abort(): このメソッドは通常、スレッドを終了するために使用されます

  • Suspend(): このメソッドは、未完了のスレッドを終了しません。スレッドを一時停止するだけで、後で再開できます。

  • Resume(): Suspend() メソッドによって一時停止されたスレッドの実行を再開します

C# では、スレッド エントリは、このスレッドに何をさせるかをプログラムに知らせます。 ThreadStart エージェント (デリゲート) の場合、ThreadStart は、スレッドによって実行される関数を指す関数ポインターとして理解できます。 Thread.Start() メソッドが呼び出されると、スレッドは、によって表される関数または指す関数の実行を開始します。スレッドの開始。 さまざまな状況での ThreadState の可能な値は次のとおりです:

  • Aborted: スレッドが停止しました

  • AbortRequested: スレッドの Thread.Abort() メソッドが呼び出されていますが、スレッドはまだ停止していません

  • Background: スレッドは、プロパティ Thread.IsBackground に関連してバックグラウンドで実行されます

  • Running: スレッドは正常に実行されています

  • Stopped: スレッドは停止されました

  • StopRequested: スレッドは停止するように要求されています

  • Suspended: スレッドは一時停止されています (この状態では、Resume() メソッドを呼び出すことで再実行できます)

  • SuspendRequested: スレッドは一時停止を要求していますが、時間内に応答しません

  • Unstarted: Thread.Start() はスレッドの実行を開始するために呼び出されませんでした

  • WaitSleepJoin: Wait( などのメソッドを呼び出したため、スレッドはブロック状態にあります) )、Sleep() または Join()


2. Winform で使用されるスレッド

まず最初に、最も直接的な方法を見てみましょう。これは、.net 1.0 でサポートされている方法でもあります。ただし、この方法は .net 2.0 以降ではすでに間違った方法であることに注意してください。


public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        Thread thread = new Thread(ThreadFuntion);
        thread.IsBackground = true;
        thread.Start();
    }
    private void ThreadFuntion()
    {
        while (true)
        {
            this.textBox1.Text = DateTime.Now.ToString();
            Thread.Sleep(1000);
        }
    }
}

このコードは vs2005 または 2008 で例外をスローします: クロススレッド操作が無効です: コントロール 'textBox1' が作成されたスレッド以外のスレッドからアクセスされました これは、.net 2.0 以降のためです。では、セキュリティ メカニズムが強化され、WinForm のコントロールのプロパティへの直接クロススレッド アクセスが許可されなくなります。では、この問題を解決するにはどうすればよいでしょうか。いくつかの解決策があります。


最初の解決策: スレッドの作成時に Control.CheckForIllegalCrossThreadCalls を false に設定します。 このコードはコンパイラに次のように指示します。このクラスでは、クロススレッド呼び出しが正当であるかどうかをチェックしません (この文を追加せずに実行したときに例外がない場合、システムがデフォルトで非チェック方式を採用することを意味します)。ただし、このアプローチはお勧めできません。 CheckForIllegalCrossThreadCalls プロパティの定義を見ると、それが静的であることがわかります。つまり、プロジェクト内のどこでこの値を変更しても、グローバルに有効になります。そして通常、このようなクロススレッドアクセスに例外があるかどうかを確認します。プロジェクト内の他の誰かがこの属性を変更すると、私たちのソリューションは失敗し、別のソリューションを採用する必要があります。

2 番目のオプション

namespace TestInvoker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ThreadStart(StartSomeWorkFromUIThread));
            thread.IsBackground = true;
            thread.Start();
            //StartSomeWorkFromUIThread();
            //label1.Text = "Set value through another thread!";
        }
        private void StartSomeWorkFromUIThread()
        {
            if (this.InvokeRequired)
            {
                BeginInvoke(new EventHandler(RunsOnWorkerThread), null);
            }
            else
            {
                RunsOnWorkerThread(this, null);
            }
        }
        private void RunsOnWorkerThread(object sender, EventArgs e)
        {
            Thread.Sleep(2000);
            label1.Text = System.DateTime.Now.ToString();
        }
    }
}

上記のコードを通して、非同期を待機することで、常にメインスレッドの制御を保持するわけではないことがわかります。 winform マルチスレッド コントロールの -threaded コントロールは、クロススレッド呼び出し例外なしで完了します。

上記は、C# WinForm マルチスレッド開発 (1) Thread クラス ライブラリの内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) をご覧ください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。