[英]blocked UI in MVVM
我正在尝试按照MVVM策略构建应用程序。 不幸的是,我的原始示例(请参见下文)阻止了UI,尽管我特别呼吁调度员。 不知道为什么..有什么建议吗?
class ViewModel : INotifyPropertyChanged
{
private readonly Dispatcher _dispatcher;
private string _name;
public ViewModel()
{
_dispatcher = Dispatcher.CurrentDispatcher;
}
public string Name
{
get { return _name; }
set
{
_name = value;
InvokePropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void InvokePropertyChanged(string propertyName)
{
var e = new PropertyChangedEventArgs(propertyName);
PropertyChangedEventHandler changed = PropertyChanged;
if (changed != null)
changed(this, e);
}
public void send()
{
Action dispAc = () => NameAsync();
_dispatcher.BeginInvoke(dispAc);
}
private void NameAsync()
{
Name = "name1";
Thread.Sleep(5000);
}
}
PS。 第一个回复澄清了一个问题,谢谢。 对于那些不使用4.5的人,我使用
Task.Factory.StartNew(dispatchAction);
休息是一样的。
不要将Dispatcher.CurrentDispatcher
用于此任务。 Dispatcher.CurrentDispatcher
您带来当前正在执行的线程,可能是UI线程。 这意味着,在UI线程中调用NameAsync()
函数,当然仍然阻止UI。 您可以使用Task.Run()异步执行您的方法以避免阻止UI:
Action dispAc = () => NameAsync();
Task.Run(dispAc);
您正在调度... UI线程的工作。 在不同的线程上完成工作,然后,当您完成后,将UI更新分发到UI线程。
除了你甚至不必。
只要您不在3.0的框架上,绑定就会自动将INPC PropertyChanged
事件封送到UI线程上。 因此,当从工作线程触摸这些属性时,您可以省去任何调度。
用你的例子......
public void send()
{
// We're on the UI thread here
Task.Run(() => NameAsync());
}
private void NameAsync()
{
// we're on some anonymous threadpool thread right now
Name = "name1";
// the event is fired on the threadpool, but bindings automatically marshall
// UI update code onto the UI thread, so it returns directly before UI is
// changed
Thread.Sleep(5000);
// and now our threadpool thread is sleeping. Good night, sweet prince.
}
改变这个,
public void send()
{
Action dispAc = () => NameAsync();
_dispatcher.BeginInvoke(dispAc);
}
对此
public void send()
{
Action dispAc = () => NameAsync();
_dispatcher.BeginInvoke(dispAc, DispatcherPriority.Background);
}
如果您不需要UI thread
来执行需要Dispatcher
的方法,那么只需使用TPL
。
默认情况下,如果您没有指定DispatcherPriority
,它将使用Normal
因此它将使用当前线程可能占用UI Thread
例如,当它尝试为其他控件执行一些Render
。
顺便说一句,如果您使用的是.NET 4.5
可以考虑使用await
和async
关键字。 如果没有,那么像其他人建议只是产生一个不同的线程来更新UI
。 与Silverlight
或WinRT
相比, WPF
的Dispatcher
足够智能,可以对主线程进行UI
更新。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.