-1

我有一个关于多线程主题的问题,如描述

    private List<Email> emails = new List<Email>();

    private void AddEmail(Email email)
    {
        lock (this.emails)
        {
            this.emails.Add(email);
        }
    }

    private void ReadEmails()
    {
        foreach (Email email in this.emails)
        {
            Print(email);
        }
    }

假设 ReadEmails 方法持续 10 秒,此时调用 AddEmail。那么是否会出现任何错误?

4

2 回答 2

2

您的ReadEmails方法不是线程安全的。你有几个选择。

选项1:

您可以lock在整个foreach循环周围放置一个。

private void ReadEmails()
{
  lock (emails)
  {
    foreach (Email email in this.emails)
    {
      Print(email);
    }
  }
}

选项#2:

您可以在lock. 然后您可以无锁地迭代复制。

private void ReadEmails()
{
  List<Email> copy;
  lock (emails)
  {
    copy = new List<Email>(this.emails);
  }
  foreach (Email email in copy)
  {
    Print(email);
  }
}
于 2012-05-17T15:33:51.927 回答
1

您绝对应该在 Read 方法中添加 Lock 方法。如果您不这样做,则可能会在读取过程尚未完成时添加电子邮件。由于 foreach 方法要求其集合在迭代期间不可更改,因此将引发异常。

 private void ReadEmails()
    {
        lock(emails) {
             foreach (Email email in this.emails) {
                Print(email);
             }
        }
    }
于 2012-05-17T04:49:49.623 回答