2009-05-12 11 views
2

Ich habe zwei Threads in C# .. Jetzt muss ich warten, dass eine bestimmte Anweisung ausgeführt wird, bevor ich die Ausführung im anderen Thread fortsetzen kann, was offensichtlich ein Fall der Synchronisation ist. Gibt es einen Code, der dies ausführen kann, wie bei der Verwendung einer eingebauten Methode?Synchronisation von zwei Threads

Dies ist das Code-Beispiel:

public void StartAccept() 
    { 
      try 
      { 
       newSock.BeginAccept(new AsyncCallback(Accepted), newSock); 
      } 
      catch (ArgumentException) 
      { 
       MessageBox.Show("Error in arguments while using begin-accept", "Error", MessageBoxButtons.OK); 
      } 
      catch (ObjectDisposedException) 
      { 
       MessageBox.Show("socket closed while using begin-accept", "Error", MessageBoxButtons.OK); 
      } 
      catch (SocketException) 
      { 
       MessageBox.Show("Error accessing socket while using begin-accept", "Error", MessageBoxButtons.OK); 
      } 
      catch (InvalidOperationException) 
      { 
       MessageBox.Show("Invalid operation while using begin-accept", "Error", MessageBoxButtons.OK); 
      } 
      catch (Exception) 
      { 
       MessageBox.Show("Exception occurred while using begin-accept", "Error", MessageBoxButtons.OK); 
      } 

    } 

Dieser empfängt Daten von dem gewünschten Wirt, der durch den Code ausgewählt wird:

private void listBox1_Click(object sender, EventArgs e) 
    { 



     String data = (String)this.listBox1.SelectedItem; 

     ip = Dns.GetHostAddresses(data); 

     clientIP = new IPEndPoint(ip[0], 5555); 

     newSock.Bind(clientIP); 
     newSock.Listen(100); 

    } 

So, um den Empfang von Daten zu starten I der Initialisierung muß Socket zu dem bestimmten Remote-Host, der ausgeführt wird, wenn ich auf einen der in der Listbox angezeigten Hosts klicke. Dafür brauche ich die Synchronisation.

+0

Apologies Das hatte ich in der Frage vermisst. –

Antwort

-2

Java hat etwas namens Join. Ich vermute, dass es auch in C# eine vordefinierte Methode geben wird.

+0

Join wartet, bis ein Thread beendet wird, keine bestimmte Anweisung – DonkeyMaster

11

Werfen Sie einen Blick auf AutoResetEvent und ManualResetEvent. Sie sind Signale, die eine Synchronisation zwischen Threads ermöglichen.

Der erste Thread, der auf etwas warten muss, wird myEvent ausführen. WaitOne(), die blockiert, bis der andere Thread myEvent aufruft. Set().

Nehmen wir an, wir haben zwei Threads, wobei einer von ihnen eine Art Initialisierung durchführen muss, bevor der andere Thread fortfahren kann. Sie teilen dann ein AutoResetEvent zwischen den beiden, nennen wir es myEvent.

// Signal example 

using System; 
using System.Threading; 

class MySync 
{ 
    private readonly AutoResetEvent _myEvent; 
    public MySync(AutoResetEvent myEvent) 
    { 
     _myEvent = myEvent; 
    } 

    public void ThreadMain(object state) 
    { 
     Console.WriteLine("Starting thread MySync"); 
     _myEvent.WaitOne(); 
     Console.WriteLine("Finishing thread MySync"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     AutoResetEvent myEvent = new AutoResetEvent(false); 
     MySync mySync = new MySync(myEvent); 
     ThreadPool.QueueUserWorkItem(mySync.ThreadMain); 
     Console.WriteLine("Press enter to continue..."); 
     Console.ReadLine(); 
     myEvent.Set(); 
     Console.WriteLine("Press enter to continue..."); 
     Console.ReadLine(); 
     Console.WriteLine("Finishing"); 
    } 
} 

Verwechseln Sie das nicht mit einer freigegebenen Ressource, bei der die Zugriffsreihenfolge keine Rolle spielt. Wenn Sie beispielsweise eine gemeinsam genutzte Liste oder ein gemeinsames Wörterbuch haben, müssen Sie sie in einen Mutex umbrechen, um sicherzustellen, dass sie korrekt ausgeführt werden.

// Mutex example 

object mySync = new object(); 
Dictionary<int, int> myDict = new Dictionary<int, int>(); 

void threadMainA() 
{ 
    lock(mySync) 
    { 
     mySync[foo] = bar; 
    } 
} 

void threadMainB() 
{ 
    lock(mySync) 
    { 
     mySync[bar] = foo; 
    } 
} 
+1

+1 für die Antwort auf die Frage, die gestellt wurde, nicht eine, die Sie sich vorstellen. . . wie was ich getan habe. . . –

+0

ok .. Also mit dem gleichen Format des Codes, wenn meine Methode startAccept() auf das Ereignis warten listBox1_Click (Object Sender, EventArgs e) ausgeführt werden soll, was würde der Code aussehen? .. Ich bin irgendwie nicht in der Lage zu verstehen, was myEvent entsprechen würde. – Avik

+0

@Awik: Wenn Sie Ihre Frage oben mit einigen konkreten Codebeispielen bearbeiten, wäre es einfacher, Ihnen eine genauere Antwort zu geben. –

3

Sie können ein AutoResetEvent verwenden.

Im folgenden Beispiel werden zwei Methoden, die von verschiedenen Threads und DoSomethingA aufgerufen() wird ausgeführt und beendet sein, bevor DoSomethingB() startet:

AutoResetEvent resetEvent = new AutoResetEvent(false); 

void ThreadWorkerA() 
{ 
    // perform some work 
    DoSomethingA(); 

    // signal the other thread 
    resetEvent.Set(); 
} 

void ThreadWorkerB() 
{ 
    // wait for the signal 
    resetEvent.WaitOne(); 

    // perform the new work 
    DoSomethingB(); 
} 

Hinweis: Speichern Sie die Autoreset zu entsorgen :)