2013-02-22 3 views
6

Teil der Portierung einer Java-Anwendung auf C# ist die Implementierung eines synchronisierten Nachrichtenpuffers in C#. Mit synchronisiert meine ich, dass es für Threads sicher sein sollte, Nachrichten zu schreiben und zu lesen.Synchronisierte Methoden in C#

In Java kann dies mit synchronized Methoden und wait() und notifyAll() gelöst werden.

Beispiel:

public class MessageBuffer { 
    // Shared resources up here 

    public MessageBuffer() { 
     // Initiating the shared resources 
    } 

    public synchronized void post(Object obj) { 
     // Do stuff 
     wait(); 
     // Do more stuff 
     notifyAll(); 
     // Do even more stuff 
    } 

    public synchronized Object fetch() { 
     // Do stuff 
     wait(); 
     // Do more stuff 
     notifyAll(); 
     // Do even more stuff and return the object 
    } 
} 

Wie ich etwas ähnliches in C# erreichen kann?

+1

Verwandte: http://stackoverflow.com/questions/541194/c-sharp-version-of-javas-synchronized-keyword – sshow

+0

@stigok nicht verwandt, es ist ein Duplikat –

+0

nicht duplizieren, sie warten nicht erwähnt() und notifyAll() – Dimme

Antwort

4

Try this:

using System.Runtime.CompilerServices; 
using System.Threading; 

public class MessageBuffer 
{ 
    // Shared resources up here 

    public MessageBuffer() 
    { 
     // Initiating the shared resources 
    } 

    [MethodImpl(MethodImplOptions.Synchronized)] 
    public virtual void post(object obj) 
    { 
     // Do stuff 
     Monitor.Wait(this); 
     // Do more stuff 
     Monitor.PulseAll(this); 
     // Do even more stuff 
    } 

    [MethodImpl(MethodImplOptions.Synchronized)] 
    public virtual object fetch() 
    { 
     // Do stuff 
     Monitor.Wait(this); 
     // Do more stuff 
     Monitor.PulseAll(this); 
     // Do even more stuff and return the object 
    } 
} 
+3

Ich mag es nicht, MethodImplOptions.Synchronized zu verwenden, weil es das Äquivalent von " Sperren Sie dies "für jede Methode. Und "lock this" wird als etwas zwielichtig angesehen, da es die Möglichkeiten von Deadlocks erhöht. –

+1

Ich stimme @MatthewWatson zu. Sie sollten MethodImplOptions.Synchronized vermeiden und stattdessen explizite Sperren verwenden. – Patrik

+0

Die Frage war, wie man das in C# erreicht, nicht was sympathischer wäre. –

6

In .NET können Sie die lock -Anweisung wie verwenden in

object oLock = new object(); 
lock(oLock){ 
    //do your stuff here 
} 

Was Sie suchen mutexes oder Ereignisse sind. Sie die ManualResetEvent -Klasse verwenden können und einen Thread warten über

ManualResetEvent mre = new ManualResetEvent(false); 
... 
mre.WaitOne(); 

Der andere Thread schließlich ruft

mre.Set(); 

machen den anderen Thread zu signalisieren, dass es weitergehen kann.

Look here.

+0

Konnte 'ManualResetEvent' für einen' Mutex' Semaphor ersetzt werden? – Dimme

+1

Ja, aber Sie würden zwei davon brauchen. Eine für die Signalisierung jedes Threads. In der Art und Weise, wenn der erste Thread ein Objekt erstellt, um dies zu signalisieren, und der zweite, um anzuzeigen, dass das Objekt verbraucht wurde. Wenn Sie viele Objekte erstellen möchten, können Sie natürlich einen anderen Ansatz wählen. Es hängt von der Situation ab. Aber Ereignisse passen zu vielen Situationen. Informationen finden Sie in der Dokumentation zu [MSDN] (http://msdn.microsoft.com/en-us/library/ms173179.aspx). –