简体   繁体   English

多线程和锁定

[英]Multithreading and lock

I have a question in multithreading subject as describe 我在描述多线程主题时遇到问题

    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);
        }
    }

Assume the ReadEmails method lasts in 10s and at that time the AddEmail is called. 假定ReadEmails方法持续10秒钟,然后调用AddEmail。 So does any error occur? 那么会发生任何错误吗?

Your ReadEmails method is not thread-safe. 您的ReadEmails方法不是线程安全的。 You have a couple of options. 您有两种选择。

Option #1: 选项1:

You can place a lock around the entire foreach loop. 您可以在整个foreach循环中放置一个lock

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

Option #2: 选项2:

You can make a copy of the list inside a lock . 您可以在lock复制列表。 Then you can iterate the copy lock-free. 然后,您可以无锁定地迭代副本。

private void ReadEmails()
{
  List<Email> copy;
  lock (emails)
  {
    copy = new List<Email>(this.emails);
  }
  foreach (Email email in copy)
  {
    Print(email);
  }
}

You should definitely add the Lock method in the Read method. 您绝对应该在Read方法中添加Lock方法。 If you do not do this, there is a possibility that the email is added when the Read process hasn't been completed yet. 如果不这样做,则有可能在尚未完成“读取”过程时添加电子邮件。 Since the foreach method requires its collection to be unchangeable during the iteration, the exception will be raised. 由于foreach方法要求其集合在迭代过程中不可更改,因此将引发异常。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM