1

このコードがデッドロックを引き起こさない理由を説明してもらえますか?

static Object listlock = new Object();

void StartAsync()
{
    System.Threading.Tasks.Task.Factory.StartNew(() => 
        {
            lock(listlock)
                base.OnPropertyChanged("MyList");
        });
}

 public ObservableCollection<MyObjects> MyList
 {
    get
    {
         lock(listlock)
             return  new ObservableCollection<MyObjects>(_myObjectList);
    }
 }

背景
の詳細​​:プログラムはMVVMパターンを使用しており、 MyListWPFUIのデータグリッドにバインドされています_myObjectsは、オブジェクトの単なるランダムなリストです。OnPropertyChange は、MyListから新しいデータを取得する必要があることをUIに通知し、UIが実際にデータを取得するかどうかを気にせずに戻るためですか?OnPropertyChangedが別のスレッドで呼び出されることは知っていますが、UIは単一のスレッドに存在するため(Ooではありません)、通知を受けるスレッドはデータを取得するスレッドでもあります。そのせいでロックが解除できなかったと思いますか?



4

2 に答える 2

3

シングルロックでデッドロックが発生するには、最初のスレッドがロックを取得し、2番目のスレッドが同じロックを取得するのを待つような方法で2つのスレッドが必要です。それ以外の場合、デッドロックは発生しません(つまり、ステートメント内で他のスレッドを待機する必要がないか、スレッドが1つだけ含まれます)。 lock

将来の読者への注意-以下はWPFの場合に起こることではありません-svickの回答を参照してください。同じスレッドに2つのロックがあるデッドロックがない一般的な例:

MyList考えられるケースの1つは、同じスレッドでの同期通知に応答してOnPropertyChanged呼び出しのリスナーが呼び出される場合です(呼び出されたときに呼び出しスタックを確認してくださいMyList)。この場合lock、ロックを要求しているスレッドがすでにロックを保持しているため、nestedは何もしません。

于 2013-03-27T02:17:25.813 に答える
3

ここでの重要な認識は、のハンドラーがUIスレッドにPropertyChangedアクセスするコードをスケジュールしますが、それが終了するのを待たないということです。MyList

したがって、考えられる一連のイベントの1つは次のとおりです。

  1. StartAsync()バックグラウンドスレッドのロックを取得します。
  2. PropertyChangedのためMyListに上げられます。
  3. UIスレッドにPropertyChangedアクセスするスケジュールコードのハンドラー。MyList
  4. PropertyChanged返品のハンドラー。
  5. ロックが解除されます。
  6. UIスレッドはにアクセスしようとしますMyList
  7. UIスレッドは、他のスレッドがロックを所有していないため、待機せずにロックを取得します。
  8. …</li>

別の言い方をすれば、あなたが期待したのは、のハンドラーPropertyChangedが次のようなことをするということです。

Dispatcher.Invoke(() =>
{
    if (e.PropertyName == "MyList")
    {
        var newList = model.MyList;
        // set newList as the current value of some binding
    }
});

しかし実際には、次のようなことをします(唯一の違いは最初の行です):

Dispatcher.BeginInvoke(() =>
{
    if (e.PropertyName == "MyList")
    {
        var newList = model.MyList;
        // set newList as the current value of some binding
    }
});
于 2013-03-27T18:51:40.820 に答える