2016-07-04 76 views
-3

我有以下鎖定方案,它似乎錯過了一段時間的鎖,讓2個代碼實例並行運行。希望你能幫助你分析/修復代碼。c#鎖不起作用(?)

public delegate void _D(A a);  

namespace ExternalDll { 
    public event _D D; 
} 

namespace MainSpace { 
    ExternalDll _externalDll; 
    public static object lockObj = new object(); 
    public static int counter = 0; 
    . 
    . 
    _externalDll.D += new _D(myEventHandler); 
    . 
    . 
    void myEventHandler(A a) { 
     lock (lockObj) { 
      counter++; 
      // do staff, printouts, etc. 
      Console.WriteLine("First={0}\n", counter); 
      // do other staff 
      Console.WriteLine("Second={0}\n", counter); 
     } 
    } 
} 

ExternalDll是一個dll文件,它接收信息a(類型A)的網絡通信。它用一個輸入來調用事件D.

主命名空間將myEventHandler註冊到由ExternalDll觸發的事件D. 在myEventHanlder中有一個鎖,因此預期的行爲是鎖部分內的代碼不會在任何時候多次執行。

但是,在運行應用程序時,它有時會達到鎖定代碼「並行」執行兩次的情況。例如,我可能會看到打印輸出:

First=0 
First=1 
Second=0 
Second=1 

這種情況尤其是在很短的時間長度(<爲1us)到externalDll內到達該突發網絡事件的情況。

我的問題/請求是:

  • 什麼可以使鎖聲明中錯誤行爲。允許2個鎖定代碼的實例?

  • 如何改進代碼,使其具有所需的鎖定行爲。

感謝,

-Moshe。

+3

它鎖定變量'theLock',但我看不到賦值給它的值,是不是要鎖定'lockObj'? – prospector

+0

是否有其他代碼寫入計數器? – usr

+0

Prospector上面說過,你的示例代碼使用「theLock」,但意味着它應該使用「lockObj」。也許清理一下你的例子?除此之外,「//其他人員」在事件處理程序完成之前是否會調用任何會導致另一個回調的東西? –

回答

0

不知道說什麼。猜測會是兩個應用程序域正在創建,因爲您正在使用一些產生多個應用程序域的內容,例如Asp.net有時會爲http模塊做這件事。

+0

是的,很可能OP開始他的應用程序衆多倍。 – VMAtm

+0

我的應用程序是普通計算,而不是Web服務器或類似的東西。我在運行時只看到一個控制檯窗口。 – Moshe

+0

也許還會打印lockObj的地址,以便看到 - 可能是做一些奇怪的編組工作。 – keith