2013-02-22 16 views
6

Częścią przeniesienia aplikacji Java do C# jest zaimplementowanie zsynchronizowanego bufora komunikatów w języku C#. Przez synchronizację mam na myśli to, że wątki powinny być bezpieczne, aby pisać i odczytywać wiadomości do iz niego.Metody zsynchronizowane w C#

W języku Java można to rozwiązać za pomocą metod synchronized i wait() i notifyAll().

Przykład:

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

Jak mogę osiągnąć coś podobnego w C#?

+1

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

+0

@stigok niezwiązane, to duplikat –

+0

Nie duplikat, nie wspominają o oczekiwaniu() i notifyAll() – Dimme

Odpowiedz

4

Spróbuj tego:

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

Nie lubię używać metody MethodImplOptions.Synchronized, ponieważ ma ona odpowiednik " zablokuj to "dla każdej metody. I "zablokować to" jest uważane za nieco podejrzane, ponieważ zwiększa możliwości impasu. –

+1

Zgadzam się z @MatthewWatson. Należy unikać metody MethodImplOptions.Synchronized i zamiast tego używać jawnych blokad. – Patrik

+0

Pytanie brzmiało, jak to osiągnąć w języku C#, a nie co byłoby bardziej sympatyczne. –

6

W .NET można użyć lock -statement jak w

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

Co szukasz są muteksy lub zdarzenia. Można użyć ManualResetEvent -class i zrobić czekać gwintu poprzez

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

Drugi wątek ostatecznie nazywa

mre.Set(); 

zasygnalizować innym wątku, że można go kontynuować.

Wygląd here.

+0

Czy można zastąpić 'ManualResetEvent' dla semafora' Mutex'? – Dimme

+1

Tak, ale potrzebujesz dwóch z nich. Jeden do sygnalizowania każdego wątku. W ten sposób, gdy wątek jeden utworzył obiekt, aby zasygnalizować to, a drugi sygnalizował, że obiekt został zużyty. Oczywiście, jeśli chcesz stworzyć wiele obiektów, możesz wybrać inne podejście. To zależy od sytuacji. Ale wydarzenia pasują do wielu sytuacji. Zobacz dokumentację na [MSDN] (http://msdn.microsoft.com/en-us/library/ms173179.aspx). –