使用Linq-to-XML插入,带有线程

时间:2009-02-20 00:03:45

标签: linq multithreading linq-to-xml

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

我们最近在我们的网络群集上超载了,我不得不从我的屁股中快速过载.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线程是否安全?)。可悲的是我的两个临LINQ和LINQ在行动的书籍没有在这个问题上碰。

这很好用,我们捕获了20多分钟的电子邮件,我们超载了。只是想知道是否有更好的方法;或者,如果它首先锁定它就太过分了。

3 个答案:

答案 0 :(得分:2)

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

假设正在遵循MS自己的指导原则。

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

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

答案 1 :(得分:2)

以这种方式保存文件本身并不是线程安全的,因此使用静态锁定句柄是明智的。

答案 2 :(得分:1)

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

  • 不需要跨线程同步对静态方法的调用
  • 应该跨线程同步对同一实例对象的调用