在我的wpf应用程序中,我的viewmodel中耗时的操作是使用单独的线程调用的。然而,该函数访问视图模型中与视图中的对象绑定的多个属性。我试图直接访问它们,我没有看到它们被UI线程所拥有。我很想知道在线程之间直接使用它们的后果。从单独线程访问ViewModel属性
回答
您可以自由使用您的ViewModel从任何线程 - 包括阅读和写作。一个主要的例外是处理集合 - 数据绑定集合必须写在用户界面线程上,因为绑定不会自动封送到UI线程(就像简单的绑定一样)。
但是,您仍然应该考虑在任何写入的位置进行适当的同步。正常的线程同步问题会发生,因为ViewModel只是另一个类。
这就是说,通常情况下,您会想要在许多情况下处理稍微不同的同步。锁通常不在ViewModel上工作,因为WPF数据绑定不会锁定对象。因此,在ViewModel中需要同步时,通常应使用Dispatcher.Invoke
/BeginInvoke
将呼叫封送回用户界面线程。
作为一个例子,如果我有一个'ToggleButton'绑定到虚拟机中的'bool'。而且我在一个单独的线程中执行'if(bool)',我需要做些什么来保持同步,以便用户设置切换和if条件执行之间没有冲突。 – Aks
@Aks号如果你只是读取这样的值,那么你就没有问题。话虽如此,你应该(技术上)标记布尔易变性。有关详细信息,请参阅:http://stackoverflow.com/questions/458173/can-ac-sharp-thread-really-cache-a-value-and-ignore-changes-to-that-value-on-ot/458193 #458193 –
除了通常的线程安全问题之外,没有任何后果。虚拟机性能通常存在问题的唯一因素是ObservableCollections
,它们具有线程关联性。
如果我真的要使用锁,是不是很可能UI线程挂起? – Aks
这是真的 - 但“通常的线程安全问题”往往需要不寻常的解决方法,因为WPF将忽略您尝试使用的任何锁定或标准线程同步。 –
如果使用这个扩展您的ObservableCollection,你可以从一个单独的线程更新:
/// <summary>
/// Source: New Things I Learned
/// Title: Have worker thread update ObservableCollection that is bound to a ListCollectionView
/// http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/have-worker-thread-update-observablecollection-that-is-bound-to-a.aspx
/// Note: Improved for clarity and the following of proper coding standards.
/// </summary>
/// <param name="e"></param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// Use BlockReentrancy
using (BlockReentrancy())
{
var eventHandler = CollectionChanged;
// Only proceed if handler exists.
if (eventHandler != null)
{
Delegate[] delegates = eventHandler.GetInvocationList();
// Walk thru invocation list
foreach (NotifyCollectionChangedEventHandler handler in delegates)
{
var currentDispatcher = handler.Target as DispatcherObject;
// If the subscriber is a DispatcherObject and different thread
if ((currentDispatcher != null) &&
(currentDispatcher.CheckAccess() == false))
{
// Invoke handler in the target dispatcher's thread
currentDispatcher.Dispatcher.Invoke(
DispatcherPriority.DataBind, handler, this, e);
}
else
{
handler(this, e);
}
}
}
}
}
/// <summary>
/// Overridden NotifyCollectionChangedEventHandler event.
/// </summary>
public override event NotifyCollectionChangedEventHandler CollectionChanged;
- 1. 从单独的线程访问TMediaPlayer.Position
- 2. 从不同的线程访问属性
- 3. 如何从另一个ViewModel访问ViewModel的属性?
- 4. 单独访问样式属性
- 5. NHibernate LazyLoad单独属性访问
- 6. 在视图中访问ViewModel属性
- 7. MVC中的ViewModel的访问属性
- 8. 从单独的线程访问表单控件
- 9. 从单独的JS文件访问Play Framework模板属性
- 10. 如何从单独的JavaScript文件访问模型属性? (MVC)
- 11. Java的访问线程的类属性
- 12. 从单独的线程/类设置控制属性
- 13. 尝试访问另一个ViewModel中的ViewModel公共属性?
- 14. 从ViewModel访问TreeView
- 15. 从一个单独的线程访问app_globals
- 16. 从javascript中的单独线程传递/访问值
- 17. 从单独的线程访问ASP.NET缓存?
- 18. 从单独的线程和类访问WinForms控件
- 19. 如何从html中访问viewmodel中的属性?
- 20. 如何从html代码访问viewmodel中的对象的属性?
- 21. 从另一个ViewModel访问另一个属性
- 22. 如何从我的ViewModel访问视图属性?
- 23. ASP.NET MVC - 如何从ViewModel访问特定属性?
- 24. 从函数访问表单的属性
- 25. 从另一个表单访问属性
- 26. 从另一个线程的ViewModel更新INotifyPropertyChanged属性WinRT
- 27. Silverlight:Parent ViewModel属性值为Child ViewModel属性
- 28. 访问/从不同的线程更改UI元素属性
- 29. 从许多类/线程访问属性的Java模式
- 30. 复制从不同线程访问的NSString的内存属性
你改变'ViewModel'或只是阅读它单独的线程? – SliverNinja
只是单独的线程 – Aks