2009-08-10 4 views
4

Ich muss sicherstellen, dass, sobald die Ausführung eine Methode trifft, das Steuerelement von dieser Methode nicht von einem anderen Thread geändert wird. Im Grunde, dachte ich, in etwa wie folgt:Sperren Sie ein Winforms-Steuerelement

private void doSomeWork(Control control) { 
    lock (control) { 
     // do some stuff with the control... 
    } 
} 

Ist dies eine schlechte Idee?

Edit:

Eigentlich, was ich versuche, zu tun ist, um sicherzustellen, dass die Steuerung nicht von einem anderen Thread angeordnet wird, während ich einige der Methoden der Kontrolle auszuführen (was, nebenbei bemerkt, wird über Reflexion ausgeführt werden).

Antwort

3

In einer Anwendung, die sich gut verhält, sind Windows Forms-Steuerelemente bereits auf nur einen Thread beschränkt. Wenn ein Thread versucht, auf ein Steuerelement zuzugreifen, das in einem anderen Thread erstellt wurde, wird eine Ausnahme ausgelöst.

Es ist nichts falsch an Ihrem Code, nur wissen, dass es gerade meist nutzlos ist, wenn Sie Ihren Weg durch den Schutz hacken (was möglich ist).

Wenn Sie in einem Arbeits-Thread Daten erstellen oder bearbeiten, sendet der Arbeits-Thread normalerweise ein Ereignis an den UI-Thread, um die Benutzeroberfläche zu aktualisieren. Auf keinen Fall sollte ein funktionierender Thread die Benutzeroberfläche selbst aktualisieren, da dies automatisch fehlschlägt.

0

Eigentlich Fernando, es ist keine schlechte Idee, aber es ist nicht die richtige Art, auf Sperren zu schauen. Sie müssen genau lesen, was die lock-Anweisung funktioniert in .Net:

http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.80).aspx

ich denke, dass aus Ihrer Aussage, die Sie das ganze Objekt erwarten gesperrt werden, oder irgendwie sicher zum Einfädeln gemacht werden, da das Objekt iteself wird in einem gesperrten Codeblock verwendet. Was tatsächlich passiert, ist, dass der Codeblock gesperrt ist und nicht von zwei oder mehr Threads zur selben Zeit ausgeführt werden darf. Wenn dieser Codeabschnitt der einzige Ort ist, an dem Sie auf dem Steuerelement arbeiten, dann sind Sie in Ordnung, sonst müssen Sie Synchronisierungssperren für das Objekt selbst durchführen.

0

Sie mit Gewinden nicht viel Erfahrung in der Arbeit haben, aber, vielleicht schlage ich werde Sie das Formular-Steuerelement in einem neuen Thread starten einen anonymen Delegierten mit:

t= new Thread(delegate() { 
    MyMethodToInvokeTheWinFormControl(); 
    }); 

t.Start(); 
0

Es hängt ganz davon ab, was Du meinst mit "nicht verändert".

Wenn Ihre Bedeutung ist "jeder andere Thread kann dieses Steuerelement überhaupt nicht ändern", dann funktioniert die Sperre nicht.

Ein Schloss in diesem Sinne ist nicht wie ein normales Schloss an einer Tür zu einem Haus. Es ist eher wie eine kleine gelbe Notiz, die "Gesperrt" sagt. Solange andere Threads die Notiz lesen und sich daran halten, was sie sagt, sollte es in Ordnung sein, aber jeder andere Thread, der sich überhaupt nicht um die Notiz kümmert, wird natürlich nicht daran gehindert, mit Ihrem Steuerelement zu verfahren.

In jedem Fall, was genau versuchen Sie zu erreichen? Sie sollten niemals mit Steuerelementen von anderen als dem Hauptthread verwirren, so dass das Problem nicht in erster Linie existieren sollte.

Stattdessen sollten Sie alle Arbeiten an der Steuerung auf den Hauptthread mithilfe der Methode Invoke auf der Steuerung übertragen.