use*_*971 0 c# wpf multithreading dependency-properties dispatcher
我使用下面的代码来显示WPF(MVVM)应用程序中的进度条状态,该应用程序基本上是在一个线程上,但是如果我在调度程序线程上放置它的状态没有在UI上更新.
有线程:
Main()
{
Thread LoadApp = new Thread(MyData);
LoadApp.Start();
}
public void MyData()
{
ProgMessage = "10%";
ProgValue = 10;
var varAction = new List<Func<object>>();
varAction .Add(() => (MainViewMode1)ViewModel1.ViewModel1);
varAction .Add(() => (MainViewMode2)ViewModel2.ViewModel2);
varAction .Add(() => (MainViewMode3)ViewModel3.ViewModel3);
foreach (var action in varAction )
{
var obj = action();
ProgressMessage = // My message from VM
ProgressBarValue += // My message valuefrom VM;
}
Run Code Online (Sandbox Code Playgroud)
}
这工作正常但是从现在开始我使用依赖属性我得到了交叉线程异常(STA)所以我将代码更改为:
Main()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
MyData();
}));
}
public void MyData()
{
ProgMessage = "10%";
ProgValue = 10;
var varAction = new List<Func<object>>();
varAction .Add(() => (MainViewMode1)ViewModel1.ViewModel1);
varAction .Add(() => (MainViewMode2)ViewModel2.ViewModel2);
varAction .Add(() => (MainViewMode3)ViewModel3.ViewModel3);
foreach (var action in varAction )
{
var obj = action();
ProgressMessage = // My message from VM
ProgressBarValue += // My message valuefrom VM;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我摆脱了线程错误,但它没有更新UI上的进度条状态?
这有什么线索吗?
在放弃对调度程序线程的控制之前,UI元素不会更新.通常你会通过返回事件循环来做到这一点,这通常意味着只返回.但是如果你在循环中有大量的工作要做,那那就不太实际了.所以一般来说,你不希望在UI线程上做这种工作.
当你说你"使用依赖属性"时,你的意思是你的ViewModel类的属性是依赖属性吗?您可能想重新考虑这一点,因为它会阻止多线程使用.如果您将它们设为普通的非自动属性,您仍然可以使用数据绑定将它们连接到UI.要在属性更改时让UI更新,您需要实现INotifyPropertyChanged
,并且您使属性引发更改通知,然后您将发现您能够像在第一个示例中那样在工作线程上工作,如果你将这些属性绑定到UI,你将不会获得线程异常,并且它会更新.
(WPF的数据绑定系统检测绑定属性何时在UI线程以外的线程上发生更改,并自动安排从正确的线程更新UI.但如果要利用此功能,则无法在VM中使用DP ,因为DPS具有线程亲和力.)
DoEvents
其他人提出的风格方法确实有效,但这是有问题的,我避免使用它.它可以实现重新入门 - 如果用户以导致事件处理程序运行的方式与您的应用程序交互,它们将在该调用内部运行Dispatcher.PushFrame
.这不一定是个问题,但很容易搞得一团糟.
另一种方法是在工作线程上进行工作,但Dispatcher.Invoke
用于调用更新ProgressMessage
和ProgressBarValue
属性的方法.这样,您的工作发生在工作线程上(让UI线程可以自由更新),但您将在UI线程上更新这些DP,从而避免错误.
归档时间: |
|
查看次数: |
6828 次 |
最近记录: |