2013-02-22 46 views
6

將Java應用程序移植到C#的一部分是在C#中實現同步的消息緩衝區。通過同步,我的意思是線程應該是安全的寫入和讀取消息。C#中的同步方法

在Java中,這可以使用​​方法和wait()和和notifyAll()來解決。

例子:

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

我怎樣才能實現在C#中類似的東西?

+1

相關:http://stackoverflow.com/questions/541194/c-sharp-version-of-javas-synchronized-keyword – sshow 2013-02-22 15:31:02

+0

@stigok無關,它是重複的 – 2013-02-22 15:35:14

+0

不重複,他們沒有提及wait()和notifyAll() – Dimme 2013-02-22 15:40:02

回答

4

試試這個:

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

我不喜歡使用MethodImplOptions.Synchronized,因爲它的作用與「鎖定這個「每種方法。而「鎖定這個」被認爲有點狡猾,因爲它增加了死鎖的可能性。 – 2013-02-22 15:35:56

+1

我同意@MatthewWatson。您應該避免使用MethodImplOptions.Synchronized,而應使用顯式鎖。 – Patrik 2013-02-22 15:41:39

+0

問題是如何在C#中實現這一點,而不是更可愛的。 – 2013-02-22 15:45:41

6

在.NET中你可以使用lock語句來像

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

你在找什麼是互斥或事件。 您可以通過

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

使用ManualResetEvent -class並讓一個線程等待另一個線程最終調用

mre.Set(); 

信號另一個線程,它可以繼續。

Look here

+0

可以'ManualResetEvent'替代'Mutex'信號? – Dimme 2013-02-22 16:02:14

+1

是的,但你需要兩個。一個用於指示每個線程。以這種方式,當線程創建一個對象來發信號,第二個線程發信號通知對象已被使用。當然,如果你想創建很多對象,你可能會選擇一種不同的方法。這取決於實際情況。但事件適合很多情況。請參閱[MSDN]上的文檔(http://msdn.microsoft.com/en-us/library/ms173179.aspx)。 – 2013-02-22 16:05:56