多线程和锁定
本文关键字:锁定 多线程 | 更新日期: 2023-09-27 18:34:21
我在多线程主题中有一个问题,如描述
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);
}
}
假设 ReadEmail 方法持续 10 秒,此时调用 AddEmail。那么会发生任何错误吗?
您的ReadEmails
方法不是线程安全的。您有几个选择。
选项#1:
您可以在整个foreach
环周围放置一个lock
。
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);
}
}
您绝对应该在 Read 方法中添加 Lock 方法。 如果不这样做,则有可能在读取过程尚未完成时添加电子邮件。 由于 foreach 方法要求其集合在迭代期间不可更改,因此将引发异常。
private void ReadEmails()
{
lock(emails) {
foreach (Email email in this.emails) {
Print(email);
}
}
}