2016-11-14 197 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

搜索確切的錯誤信息,例如[這裏](http://stackoverflow.com/q/142003/1997232)是winforms的重複,[這裏](http://stackoverflow.com/q/11923865/1997232)是wpf。 – Sinatr

+0

這不是一個'TextBox'它是一個'PictureBox' @Sinatr – Forrobodo

+0

這個問題與控制類型無關,是的,你可以*調用一個'PictureBox' *。我會開始閱讀相應的鏈接問題的答案,如果它仍然不清楚你需要做什麼,那麼:1)爲問題添加相應的標籤(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; }); 
相關問題