3

确保线程安全的 Linq-to-XML 编写的最佳方法是什么?

我们最近在我们的 Web 集群上超载,我不得不从我的屁股中提取一个快速的重载.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 书籍并未涉及该主题。

这很好,我们在超载的 20m 中捕获了大量电子邮件。只是想知道是否有更好的方法;或者,如果一开始就锁定它只是矫枉过正。

4

3 回答 3

2

通常,在 MSDN 上,如果类型或非静态成员未明确标记为线程安全,则不是。一般静态成员应该是。

假设正在遵循 MS 自己的指导方针。

但是,您似乎希望在执行加载/编辑/保存组时保护文件不被更改。如果您维护一个锁,那只有线程安全(如果您直接创建具有适当读/写的 FileSram,然后将其(使用 StreamReader 或 StreamWriter 包装器)传递给 Load 和 Save 方法,这很容易)。

仅使用锁的缺点是文件打开方法(包括那些在对象构造上隐式调用的方法)如果文件被锁定会抛出异常。因此,您可能需要一个锁来避免这种情况(如果您涉及多个进程或应用程序域,则可能需要一个互斥锁)。

于 2009-02-20T00:11:21.963 回答
2

以这种方式保存文件本质上不是线程安全的,因此使用静态锁句柄很聪明。

于 2009-02-20T00:21:54.137 回答
1

我猜 LINQ 对象遵循与任何 .Net SDK 对象相同的线程安全准则:

  • 对静态方法的调用不需要跨线程同步
  • 对同一个实例对象的调用应该跨线程同步
于 2009-02-20T00:12:41.850 回答