トップ  >  サンプルソース  >  有効ではないスレッド間の操作(C#/VB.NET)

有効ではないスレッド間の操作(C#/VB.NET)

2010年10月29日

"有効ではないスレッド間の操作"と言う例外が発生する事があります。原因はFromとは別のスレッドからFrom上のコントロールにアクセスしたからです。

しかし、あるオマジナイをすると例外が発生しなくなります。

このサンプル(ソース/コード)は、MyProc1を呼び出すスレッドを作成すると例外が発生します。MyProc2を呼び出すスレッドを作成すると例外は発生しません。

' -----------------------------------------------------------
' 有効ではないスレッド間の操作のサンプル(VB.NET/VS2005)
Private MyThread As System.Threading.Thread
Private Sub Form1_Load( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

    ' スレッド開始
    MyThread = New System.Threading.Thread( _
        New System.Threading.ThreadStart(AddressOf MyProc1))
    MyThread.Start()
End Sub

Private Sub Form1_FormClosed( _
    ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.FormClosedEventArgs) _
    Handles MyBase.FormClosed

    ' スレッド終了
    MyThread.Abort()
End Sub

' 例外が発生するサンプル
Private Sub MyProc1()
    Do While (True)
        System.Threading.Thread.Sleep(1000)
        TextBox1.Text = "abc"   ' ここで例外が発生する
        ' エラーメッセージ
        ' "有効ではないスレッド間の操作:
        ' コントロールが作成されたスレッド以外の
        ' スレッドからコントロール 'TextBox1' が
        ' アクセスされました。"
    Loop
End Sub

' 例外が発生しないサンプル
Private Delegate Sub D_UpdTextBox(ByVal txt As String)
Private Sub MyProc2()
    Do While (True)
        System.Threading.Thread.Sleep(1000)
        TextBox1.Invoke( _
            New D_UpdTextBox(AddressOf UpdTextBox), "abc")
    Loop
End Sub
Private Sub UpdTextBox(ByVal txt As String)
    TextBox1.Text = txt
End Sub
' -----------------------------------------------------------

// ----------------------------------------------------------
// 有効ではないスレッド間の操作のサンプル(C#.NET/VS2005)
private System.Threading.Thread MyThread;

private void Form1_Load(
    object sender, EventArgs e)
{
    // スレッド開始
    MyThread = new System.Threading.Thread(
        new System.Threading.ThreadStart(MyProc1));
    MyThread.Start();
}

private void Form1_FormClosed(
    object sender, FormClosedEventArgs e)
{
    // スレッド終了
    MyThread.Abort ();
}

// 例外が発生するサンプル
private void MyProc1()
{
    while (true)
    {
        System.Threading.Thread.Sleep(1000);
        textBox1.Text = "abc";  // ここで例外が発生する
        // エラーメッセージ
        // "有効ではないスレッド間の操作:
        // コントロールが作成されたスレッド以外の
        // スレッドからコントロール 'textBox1' が
        // アクセスされました。"
    }
}

// 例外が発生しないサンプル
private delegate void D_UpdTextBox(String txt);
private void MyProc2()
{
    while (true)
    {
        System.Threading.Thread.Sleep(1000);
        textBox1.Invoke(
            new D_UpdTextBox(UpdTextBox), "abc");
    }
}
private void UpdTextBox(String txt)
{
    textBox1.Text = txt;
}
// ----------------------------------------------------------
スポンサーサイト

ガベージコレクションとデリゲート(C#/VB.NET) | トップページへ戻る | キーボード監視(C#/VB.NET)

このページのトップに戻る

コメント

名前
題名
メールアドレス
WEBサイト
 
コメント
パスワード
  管理者にだけ表示を許可する

このページのトップに戻る

トラックバック

このページのトップに戻る