gpt4 book ai didi

c# - 为什么代码不会死锁

转载 作者:太空宇宙 更新时间:2023-11-03 19:17:00 26 4
gpt4 key购买 nike

有人可以向我解释为什么这段代码不会导致死锁吗?

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 模式,MyList 绑定(bind)到 WPF UI 上的 Datagrid
_myObjects 只是对象的随机列表。

是不是因为 OnPropertyChange 只是通知 UI 它必须从 MyList 获取新数据并且只是返回而不关心 UI 是否实际获取数据?
我知道OnPropertyChanged 在单独的线程上调用,但 UI 存在于单个线程上(不是 O.o),因此获得通知的线程也是获取数据的线程。我会认为锁不会因此而无法释放吗?

最佳答案

这里的关键实现是 PropertyChanged 的处理程序确实在 UI 线程上安排了一些访问 MyList 的代码,但它不等待它完成

因此,一个可能的事件序列是这样的:

  1. StartAsync() 在后台线程上获取锁。
  2. 引发了 MyList
  3. PropertyChanged
  4. PropertyChanged 的处理程序调度在 UI 线程上访问 MyList 的代码。
  5. PropertyChanged 的处理程序返回。
  6. 锁被释放。
  7. UI 线程尝试访问 MyList
  8. UI 线程无需等待就获取锁,因为没有其他线程拥有它。

另一种表达方式:我认为您期望的是 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
}
});

关于c# - 为什么代码不会死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15650778/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com