2016-11-14 2 views
0

So habe ich eine Taste, die in letzter Zeit in der Lage sein wird, eine Tür durch SerialPort zu öffnen. Dazu werde ich etwas senden und auf eine Antwort warten, die bereits konfiguriert und entwickelt wurde.Steuerung, auf die von einem anderen Thread als dem Thread zugegriffen wurde, in dem sie erstellt wurde C#

Aber ich bekomme einige Probleme, um eine Thread.Sleep() zu setzen.

Dies ist, was ich in der Schaltfläche bekam:

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

Und die Demo Methode ist:

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); 
    } 
} 

Als ich die Tür öffnen wird es die „Tür geöffnet“ Meldung zeigt und wenn es versucht, die pbGreen.Show() auszuführen, stoppt die Anwendungen und ein Fehler kommt:

Cross-Thread-Oper nicht gültig: Steuerung, auf die von einem anderen Thread als dem Thread, auf dem sie erstellt wurde, zugegriffen wird

Haben Sie eine Idee, wie kann ich es lösen? Ich kann keine PictureBox

+4

Suche nach genauer Fehlermeldung, z.B. [hier] (http://stackoverflow.com/q/142003/1997232) ist ein Duplikat für winforms und [hier] (http://stackoverflow.com/q/11923865/1997232) ist für wpf. – Sinatr

+0

Dies ist keine 'TextBox' Es ist eine' PictureBox' @Sinatr – Forrobodo

+0

Das Problem ist irrelevant für die Steuerung von Typ und ja, Sie können * eine PictureBox * * aufrufen. Ich würde mit dem Lesen der entsprechenden verknüpften Fragen beginnen, wenn es noch nicht klar ist, was Sie tun müssen, dann: 1) fügen Sie entsprechende Tags zu der Frage hinzu (winforms? Wpf? ...) 2) erklären Sie, warum Sie * "nicht aufrufen können" *. Die Nachricht, die Sie erhalten, sollte gelöscht werden, sobald Sie GUI-bezogenes Material in den GUI-Thread senden/aufrufen. – Sinatr

Antwort

0

aufrufen. Die Kontrolle, auf die Sie zugreifen möchten (in diesem Fall pbGreen und höchstwahrscheinlich pbRed), wurde im Hauptthread erstellt und Sie versuchen, sie in einem anderen Thread zu aktualisieren. Sie erhalten diesen Fehler. Um das Problem zu beheben, müssen Sie Ihre Aufrufe threadsicher machen, indem Sie sie aufrufen.

private void Demo() 
{ 
    if (InvokeRequired) { 
     Invoke(new MethodInvoker(() => { Demo(); })); 
     return; 
    } 

    //Do stuff 
} 

jedoch Ihre eigene Methode machen könnte sogar noch besser:

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

Dann:

pbGreen.InvokeIfRequired(() => { pbGreen.Image = myImage; }); 
Verwandte Themen