2012-01-16 77 views
0

我正在使用C#在ASP.NET中開發一個網頁。monitor.enter(鎖)問題

許多用戶可以同時訪問該頁面。

按鈕單擊我正在調用一個具有臨界區域的功能。

我已經把這些代碼在

try 
{ 
    moniter.enter(lock)   
    salbapi.Sislemcu_Epayroll_Salffs_Bapi(Saljv_str, "N", out messdata, ref Saljv_table); 
} 
catch(Exception e) 
{ 
} 
finally 
{ 
    moniter.exit(lock). 
} 

如果2個用戶正在訪問在同一時間的功能現在假設。

生成的處理消息被交換或不交換(錯誤消息顯示給用戶)。

它不應該發生。

+0

你確定這個代碼在一個工作進程中運行?如果沒有,你可以創建你想要的所有監視器,但它們不會跨進程同步。 – 2012-01-16 13:23:24

+0

@kumar如果其中一個答案是您要求的答案,那麼將其標記爲好的形式。 – 2012-01-17 08:38:52

回答

0

你問這是否是線程安全的?如果所有線程都具有鎖定變量的可見性,那麼是的。

如果一個線程調用了方法並獲得了鎖,則將會強制另一個線程通過Monitor.Enter等待,直到第一個線程調用Monitor.Exit

0
lock(Application["Lock"]) 
{ 
    salbapi.Sislemcu_Epayroll_Salffs_Bapi(Saljv_str, "N", out messdata, ref  Saljv_table); 
} 

這確保了關鍵代碼在應用程序內一次只能執行一次,無論有多少個同時發生的頁面請求。我建議初始化Application["Lock"]在Global.asax中上的Application_Start:

public class Global : System.Web.HttpApplication 
{ 
    protected void Application_Start(object sender, EventArgs e)   
    { 
     Application["Lock"] = new object(); 
    } 

    //other handlers 
} 

我也建議你拿出的VAR一個更好的名字,使其清楚其鎖定,並沒有在其他地方重複使用死鎖的風險。

+0

我用它,但鎖內的代碼多執行一次' – 2012-01-16 12:02:17

+0

請參閱編輯。您需要使用在頁面實例之間共享的鎖定對象。記住頁面的每個請求都會生成給定頁面類的新實例,因此不會在請求之間共享具有類作用域的鎖變量。 – 2012-01-16 13:11:44

0

簡答Tudor是正確的。長答案:

moniter.enter對於這個邏輯有點低級別。嘗試使用lock語句,它是'monitor.enter()的糖;最後嘗試{...}(顯示器退出)'。此外,捕食和吃異常是非常糟糕的形式;讓異常泡沫,因此它被報告。

我會做類似

class Foo 
    { 
    static object synch = new object(); 

    void TheMethod() 
    { 
     lock (synch) 
     { 
      salbapi.Sislemcu_Epayroll_Salffs_Bapi(...); 
     } 
    } 

}

+0

這將在頁面事件處理程序的上下文中失敗,因爲同步是一個類級別的var,我們需要使用應用程序級別var(或定義一個單例,效果相同),以滿足要求。 – 2012-01-16 13:15:30

+0

邁爾斯是正確的。我的意思是使它靜止。 – 2012-01-16 18:58:47

+0

@RichardSchneider它爲我工作,但現在的問題是當2個用戶正在訪問這個。第二個用戶等到第一個完成,當兩個完成時,第一個用戶的結果顯示爲第二個,反之亦然......不知道爲什麼這是開發? – 2012-01-18 03:55:34