C# 线程安全(特别是 MVVM/WPF) [英] C# thread safety (in particular MVVM/WPF)
问题描述
我想知道我需要做什么才能使 MVVM 中的模型线程安全.假设我有以下类,它被实例化为单例:
I'm wondering what I need to do to make models thread safe in MVVM. Say I had the following class, which is instantiated as a singleton:
public class RunningTotal: INotifyPropertyChange
{
private int _total;
public int Total
{
get { return _total; }
set
{
_total = value;
PropertyChanged("Total");
}
}
...etc...
}
我的视图模型通过属性公开它:
My view model exposes it via a property:
public RunningTotal RunningTotal { get; }
我的视图绑定了一个文本块,即{Binding Path=RunningTotal.Total}
.
And my view has a textblock bound to it, i.e. {Binding Path=RunningTotal.Total}
.
我的应用程序有一个后台线程,它会定期更新 Total 的值.假设没有其他东西更新 Total,我应该怎么做(如果有的话)才能使所有这些线程安全?
My app has a background thread that periodically updates the value of Total. Assuming nothing else updates Total, what (if anything) should I do to make all this thread-safe?
现在,如果我想做类似的事情,但使用 Dictionary<>
或 ObservableCollection<>
类型的属性怎么办?哪些成员(添加、删除、清除、索引器)是线程安全的?我应该改用 ConcurrentDictionary 吗?
Now, what if I wanted to do something similar but using a property of type Dictionary<>
, or ObservableCollection<>
? Which members (add, remove, clear, indexer) are thread-safe? Should I use a ConcurrentDictionary instead?
推荐答案
我的应用程序有一个后台线程,它会定期更新 Total 的值.假设没有其他东西更新 Total,我应该怎么做(如果有的话)才能使所有这些线程安全?
My app has a background thread that periodically updates the value of Total. Assuming nothing else updates Total, what (if anything) should I do to make all this thread-safe?
对于标量属性,你不需要做任何特别的事情;PropertyChanged
事件会自动编组到 UI 线程.
For scalar properties, you don't need to do anything special; the PropertyChanged
event is automatically marshaled to the UI thread.
现在,如果我想做类似的事情但使用类型为 Dictionary<> 或 ObservableCollection<> 的属性怎么办?哪些成员(添加、删除、清除、索引器)是线程安全的?我应该改用 ConcurrentDictionary 吗?
Now, what if I wanted to do something similar but using a property of type Dictionary<>, or ObservableCollection<>? Which members (add, remove, clear, indexer) are thread-safe? Should I use a ConcurrentDictionary instead?
不,这不是线程安全的.如果您从后台线程更改 ObservableCollection
的内容,它将中断.您需要在 UI 线程上执行此操作.一种简单的方法是使用一个在 UI 线程上引发其事件的集合,例如 此处.
No, this is not thread-safe. If you change the content of an ObservableCollection<T>
from a background thread, it will break. You need to do it on the UI thread. An easy way to do it is to use a collection that raises its events on the UI thread, like the one described here.
至于Dictionary
,当它的内容发生变化时,它不会发出通知,因此无论如何也不会通知UI.
As for Dictionary<TKey, TValue>
, it doesn't raise a notification when its content changes, so the UI is not notified anyway.
这篇关于C# 线程安全(特别是 MVVM/WPF)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!