-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 メソッドを必ず追加する必要があります。これを行わないと、Read 処理が完了していないときにメールが追加される可能性があります。foreach メソッドでは、反復中にそのコレクションを変更できない必要があるため、例外が発生します。

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