2011-04-10 264 views
1

防止兩個不同的人同時執行相同方法的最佳方法是什麼?例如,用戶A與用戶B在同一頁面上。兩者都在完全同時執行該事件的代碼的同時按下頁面上的按鈕。我試圖讓其他人等待完成。ASP.NET競爭條件

有沒有一種常見的方法來做到這一點?

這裏有更多的一些信息..

這是一個簡單的遊戲,你買的網站成員(如FB上的既有遊戲)。查詢字符串是用戶的ID。我遇到了兩個人同時點擊購買的問題。一個獲得用戶,另一個則虧錢。所以我試圖在同一時間阻止購買,以防止發生。

+0

你可以在一個靜態變量上使用'lock',但是這聽起來像你會在你的應用程序中創建一個爭用點。如果是2,那麼頁面上有100個用戶呢? – CriGoT 2011-04-10 11:31:12

+4

我們可以知道方法和它在做什麼嗎?通常,對服務(RESTful,理想情況下)提出的每個請求都是獨立處理的原子單元。它通常不依賴於其他請求,特別是其他用戶上下文中的請求。很可能有更好的方法來設計這個。 – David 2011-04-10 11:32:19

回答

4

A Page將爲每個請求創建實例,因此假設您擁有的邏輯位於實例成員中,並且不訪問任何共享的內容,則不需要進行鎖定。

如果碰到共享資源,有幾種方法可以強制鎖定。一種方法是使用lock陳述,例如

private static someObject = new Object(); 

public void SomeMethod() 
{ 
    lock(someObject) 
    { 
     // do something with your shared resource. 
    } 

} 

一般來說,你的目標應該是避免使用鎖儘可能地(雖然也有在需要鎖定許多情況下)。

編輯:

如果你持有支持事務例如數據源數據就像數據庫一樣,那麼您首先需要檢查用戶嘗試購買的內容在用戶點擊頁面上的「是」與收到響應的應用程序之間的時間內尚未購買。因此,您需要檢查數據源以確定它是否已被購買,如果尚未購買,則爲該用戶「購買」該商品。這應該在交易中完成,以便它是原子的,因此如果「購買」該項目的行爲成功,您只需從用戶的賬戶中取錢。

3

您可以與[MethodImpl]屬性裝飾它:

[MethodImpl(MethodImplOptions.Synchronized)] 
public static void SomeMethod() 
{ 
    ... 
} 

這樣,只有一個線程可以執行的方法和其他人將等待。這相當於把lock放到整個方法體中。

+0

注意如果使用此方法創建死鎖。 – 2011-04-10 11:39:27

+0

根據Jeffrey Richter和他的書「CLR via C#」3rd ed。,建議不要使用此屬性。該屬性使用'this'變量的Monitor鎖,這是不推薦的。相反,建議創建一個專用實例字段進行鎖定。如果它是一個靜態方法,則該屬性使用Monitor類來鎖定對類​​型的類型對象的引用,這也是不被推薦的,並且可能導致微妙的錯誤和問題。 – 2012-02-08 00:32:56