3

ここではどのような意図が表現されていますか?:

lock(Locker)
{
    Task.Factory.StartNew(()=>
    {
        foreach(var item in this.MyNonCurrentCollection)
        {
          //modify non-concurrent collection
        }
    }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchonizationContext())
    .ContinueWith(t => this.RaisePropertyChanged("MyNonCurrentCollection"));
}

システムlockは が完了するまで (キューに) 入れますか、それともTask新しい を開始するためだけにシステムをロックしTaskますか? 後者は、役に立たない場合でもこのロックが親切であることを意味しますよね? 他人のコードから意図を見つけようとしているだけです。ここでの理想はMyNonCurrentCollection、別のスレッドによって変更されないようにすることです。

4

2 に答える 2

7

タスクが完了するまで、システムはロック (キュー) されますか?

いいえ。

システムは新しいタスクを開始するためだけにロックされますか?

はい。

後者は、役に立たない場合でもこのロックが親切であることを意味しますよね?

完全なコンテキストを見ないと常に確信できるとは限りませんが、そう思われるかもしれません。たとえば、ロックが必要なリソースに基づいて、タスクを開始する必要があるかどうかを確認する必要があるコードを書くことがあります。したがって、タスクを開始するだけのコードをロックすることが適切な場合があります。ただし、タスクを開始する以外に何もしていない場合は、おそらくそうではありません。

ここでの理想は、MyNonCurrentCollection が別のスレッドによって変更されないように保護することです。

これはそれを妨げるものではありません。


補足として、そのコレクション内のコレクションを変更するforeachことは悪い考えです。一部のコレクションは、ある種の同時変更例外をスローするだけで十分です。あまり良くないコレクションは、壊れた結果を生成するだけです。

于 2013-10-30T19:34:25.723 に答える
2

タスクがインスタンス化されて開始されるまで、システムはロックされます。Task.Factory.StartNew は非同期です。タスクに時間がかかる場合でも、ロックを長時間取得しないでください。

タスク内では、タスクの作成ではなく、実際に共有リソースをロックする必要があります。タスクが非常に迅速に完了し、ロックが解除される前にプリエンプティブにスケジュールされない限り、ロックはリソースの安全性に影響を与えません。

これはバグです、はい。

于 2013-10-30T19:35:58.780 に答える