Использование Linq-to-XML для вставки с многопоточностью - PullRequest
3 голосов
/ 20 февраля 2009

Каков наилучший способ обеспечения поточно-ориентированного 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?). Грустно сказать, что мои две книги о Pro LINQ и Linq in Action не затрагивают эту тему.

Это сработало нормально, и за 20 м мы перегрузили большое количество писем. Просто интересно, есть ли лучший способ; или, если это было просто излишним, заблокировать его.

Ответы [ 3 ]

2 голосов
/ 20 февраля 2009

Сохранение файла таким способом не является потокобезопасным, поэтому было бы разумно использовать дескриптор статической блокировки.

2 голосов
/ 20 февраля 2009

Как правило, в MSDN, если тип или нестатический член явно не помечен как потокобезопасный, это не так. Обычно статические члены должны быть.

Предполагается, что соблюдаются собственные правила MS, а именно.

Однако вы, похоже, хотите защитить файл от изменения при выполнении группы загрузки / редактирования / сохранения. И это безопасно только для потоков, если вы поддерживаете блокировку (что достаточно просто, если вы напрямую создаете FileStram с соответствующими операциями чтения / записи, а затем передаете его (с помощью обертки StreamReader или StreamWriter) методам Load и Save).

Недостатком простого использования блокировки является то, что методы открытия файла (включая те, которые неявно вызываются при построении объекта) будут вызывать исключение, если файл заблокирован. Поэтому вам может потребоваться блокировка, чтобы избежать этого (и это может быть мьютексом, если задействовано более одного процесса или домена приложения).

1 голос
/ 20 февраля 2009

Я предполагаю, что объекты LINQ следуют тем же правилам безопасности потоков, что и любой объект .Net SDK:

  • Вызовы статических методов не нужно синхронизировать между потоками
  • Вызовы к одному и тому же объекту экземпляра должны быть синхронизированы между потоками
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...