2016-11-14 5 views
0

したがって、最近はドアを開くことができるボタンがSerialPortにあります。これを行うために、私はそれに何かを送って、既に構成され開発された応答を待つでしょう。コントロールはC#で作成されたスレッド以外のスレッドからアクセスされました

しかし、私はThread.Sleep()を設定するいくつかのトラブルが発生しています。

これは私がボタンの内部で得たものである:

private void cmdOpenDoor_Click(object sender, EventArgs e) 
{ 
    Thread.Sleep(5000); 
    Task.Factory.StartNew(this.Demo); 
} 

そしてDemo方法は次のとおりです。

private void Demo() 
{ 
    string questionMark= "?"; 
    string incoming = comport.ReadExisting(); 
    string carriageReturn = "\r"; 

    comport.Write(questionMark+ "(" + carriageReturn); 

    Cursor.Current = Cursors.WaitCursor; 

    if (txtTest.Text == "@q") 
    { 
     MessageBox.Show("Door opened!", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     pbGreen.Show(); 
     pbRed.Hide(); 
    } 
    else 
    { 
     MessageBox.Show("The door is already opened!", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

私はドアを開けますと、それはメッセージとときを「ドアが開いた」と表示アプリケーションが停止し、エラーが発生すると、pbGreen.Show()を実行しようとします。

クロススレッドオペラ無効なコントロール:作成されたスレッド以外のスレッドからアクセスされたコントロール

どうすれば解決できますか?私は呼び出すことができませんPictureBox

+4

検索、例えば[here](http://stackoverflow.com/q/142003/1997232)はwinformsと重複しています。[here](http://stackoverflow.com/q/11923865/1997232)はwpfです。 – Sinatr

+0

これは 'TextBox'ではなく' PictureBox' @Sinatrです – Forrobodo

+0

問題はコントロールの種類には無関係です。そして、あなたは 'PictureBox' *を呼び出すことができます。私は質問に対応するタグを追加する(winforms?wpf?...)2)あなたがなぜ "あなたが"呼び出すことができないのかを説明する。 *。受け取ったメッセージは、GUI関連のものをGUIスレッドにディスパッチ/呼び出すとすぐに消えていくはずです。 – Sinatr

答えて

0

アクセスしようとしているコントロール(この例ではpbGreen、おそらくはpbRedも)はメインスレッドで作成されており、異なるスレッドでそれらを更新しようとしているため、このエラーが発生します。 この問題を解決するには、呼び出しによって呼び出しをスレッドセーフにする必要があります。

しかし、独自の方法でも良いかもしれ作る
private void Demo() 
{ 
    if (InvokeRequired) { 
     Invoke(new MethodInvoker(() => { Demo(); })); 
     return; 
    } 

    //Do stuff 
} 

その後
public static void InvokeIfRequired(this ISynchronizeInvoke formControl, MethodInvoker action) 
{ 
    if (formControl.InvokeRequired) { 
     formControl.Invoke(action, new object[0]); 
    } else { 
     action(); 
    } 
} 

:正確なエラーメッセージの

pbGreen.InvokeIfRequired(() => { pbGreen.Image = myImage; }); 
関連する問題