2009-02-20 88 views
3

確保線程安全的Linq-to-XML用於編寫的最佳方式是什麼?使用Linq-to-XML插入,使用線程

我們近期重載我們的網站集羣上,我不得不拉快overloaded.aspx了我的屁股來捕捉人們可以用後,當該網站變得更加敏感聯繫電子郵件。在短短的5分鐘內,我寫了這樣的:

private static object LockHandle = new object(); 

protected override void OnLoad(EventArgs e) 
{ 
    SubmitButton.ServerClick += new EventHandler(SubmitButton_ServerClick); 
    base.OnLoad(e); 
} 

void SubmitButton_ServerClick(object sender, EventArgs e) 
{ 
    string email = Email.Value.Trim(); 
    if (email.Length > 0) 
    { 
    Regex regex = new Regex(@"^([\w\-\.]+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$"); 
    if (regex.IsMatch(email)) 
    { 
     lock (LockHandle) 
     { 
     try 
     { 
      string fileName = Server.MapPath("emails.xml"); 
      XDocument xdoc = XDocument.Load(fileName); 
      xdoc.Element("emails").Add(new XElement("email", email)); 
      xdoc.Save(fileName); 
     } 
     catch {} 
     } 

     ResponseText.Text = "Thanks! We'll get back to you."; 


    } 
    } 
} 

如果Linq-to-XML是線程安全的,我無法查找;所以,理論是「讓我鎖定一個靜態對象,這將防止多次寫入」。這是最好的方法嗎?是否甚至需要(是否Linq-to-Xml線程安全?)。很遺憾,我的兩本Pro LINQ和Linq in Action書籍並沒有涉及這個主題。

這工作得很好,我們捕獲了20米的電子郵件數量,我們被超載。只是想知道是否有更好的方法;或者,如果這只是矯枉過正而將其鎖定在第一位。

回答

2

以這種方式保存文件本質上不是線程安全的,因此使用靜態鎖定句柄很聰明。

2

一般情況下,在MSDN上,如果一個類型或者非靜態成員沒有明確標記爲線程安全的事實並非如此。一般來說靜態成員應該是。

假設MS正在遵循MS自己的指導原則。

但是,您似乎希望在執行加載/編輯/保存組時保護文件不被更改。如果你維護一個鎖,這只是線程安全的(如果你用適當的讀/寫直接創建一個FileStram,然後將它(通過StreamReader或StreamWriter包裝器)傳遞給Load和Save方法,這就很容易了。

只使用一個鎖的缺點是文件的打開方式(包括隱式調用對象上的建築)將拋出一個異常,如果該文件被鎖定。因此,您可能需要鎖定才能避免此問題(如果涉及多個進程或應用程序域,則可能需要互斥鎖)。

+0

這個想法是,我不希望其他寫入失敗,而是等待輪到寫入同一個文件。我的想法是通過創建一個靜態對象並鎖定它,這會阻止所有其他線程寫入(在相同的命名空間中,是)。 是的沒有? – eduncan911 2009-02-20 00:14:29

+0

s/namespace/app-domain /和yes。 但這是關於文件和併發性,而不是XDocument。加載/操作/保存列表會導致同樣的問題。 – Richard 2009-02-20 00:30:20

1

我猜LINQ對象遵循任何.NET SDK對象遵循相同的線程安全原則:

  • 調用靜態方法不需要進行跨線程
  • 呼叫同步到同一個實例對象應該跨線程同步