可以请我解释一下为什么此代码不会导致死锁吗?
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是否实际获取Data?我知道OnPropertyChanged是在单独的线程上调用的,但是UI在单个线程上存在(不是O.o),所以被通知的线程也是获取数据的线程。我会因为这个原因而无法释放锁?
最佳答案
此处的关键实现是PropertyChanged
的处理程序确实调度了一些可访问UI线程上的MyList
的代码,但并不等待它完成。
因此,事件的一种可能的顺序是:
StartAsync()
锁定后台线程。 PropertyChanged
的MyList
。 PropertyChanged
的处理程序计划在UI线程上访问MyList
的代码。 PropertyChanged
的处理程序返回。 MyList
。 另一种表达方式:我认为您期望的是
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/