2017-10-26 11 views
2

Ich habe 4 Windows-Formulare und sie verwenden eine Methode der anderen Form. Diese Methode muss nur von einem der Formulare verarbeitet werden. Wenn ein Thread diese Methode verwenden möchte, muss er sicher sein, dass die Methode zu diesem Zeitpunkt nicht von anderen Threads aufgerufen wird.Aufruf von Methoden aus verschiedenen Threads

Ich habe eine Lösung wie die

bool methodIsBusy = false; 

void Method() 
{ 
    methodIsBusy = true; 

    //do method things 

    //done method things 

    methodIsBusy = false; 

} 

und verwenden methodIsBusy zu wissen, dass das Verfahren durch einen Faden belegt ist oder nicht. Gibt es kreativere Lösungen für dieses Problem? Vielen Dank.

+5

Wenn Sie Methoden von Formularen aus anderen Threads als dem UI-Thread aufrufen, ist es fast garantiert, dass Sie etwas falsch machen. Das wird nicht gut enden. Überdenken Sie, was Sie tun. – xxbbcc

+0

Warum? Ich erstelle 4 Formen aus einer Hauptform, durch Instatiation. Warum kann ich Main-Threads-Methoden nicht in neuen Formularen verwenden? Was kann ein Problem verursachen? –

+5

@MehmetErkol Das Problem ist nicht Aufruf der Methoden eines anderen Formulars, es ruft sie * aus einem Nicht-UI-Thread *. Sie sollten eine solche Methode immer nur über den UI-Thread * aufrufen. Da alle Aufrufe im UI-Thread enthalten sind, wissen Sie bereits, dass sie nicht gleichzeitig ausgeführt werden. – Servy

Antwort

4

Das einfachste traditionelle Muster wäre eher lock. Code innerhalb einer Sperre (bezeichnet als critical section) kann immer nur von einem Thread ausgeführt werden.

object lockObject = new object(); //Can be anything, an object will do 

void Method() 
{ 
    lock (lockObject) 
    { 

     //do method things 

     //done method things 

    }  
} 

Sie könnte theoretisch ein bool verwenden, aber man müsste busywait Code schreiben, wie folgt aus:

//Don't do this! 
while (methodIsBusy) 
{ 
    System.Threading.Thread.Sleep(10); //or some number 
} 

Diese Art von Code wird bis mit mehr Ressourcen als eine Sperre beenden, das ist genau für diesen Zweck konzipiert.

+0

In Ihrem Schloss Beispiel, wenn 1. Thread ausgeführt wird, und eine Bestellung für tread2 ist bereit für die Ausführung, was passiert? Ist der 2. Thread auf 1 zu warten. Thread, um seine Arbeit zu beenden, auszuführen oder niemals auszuführen? –

+0

Im zweiten Thread. Der Code wird am Anfang des 'lock {' -Blocks anhalten, bis der erste Thread den gleichen Block verlassen hat. –

0

Sie können eine lock verwenden, um sicherzustellen, dass nur ein Thread einen kritischen Block eingeben kann, der mit einer lock-Anweisung gekapselt ist.

-1

Werfen Sie auch einen Blick auf Monitor.TryEnter - die Sie testen können, wenn Sie eingeben können, nicht sperren und ausgehen ohne etwas zu tun. Machen Sie nur wirklich sicher, eine try {} finalley { Monitor.Exit(obj); } zu verwenden, um Ihr Sperrobj wieder freizugeben.

Verwandte Themen