If you have searched 'WPF Dispatcher', you must have known why we should use Dispatcher(System.Windows.Threading.Dispathcer) rather than Thread when we want to change UI properties asynchronously. It's something like UI is manipulated by only one single thread, if you change it in Thread, you'll get Exceptions bluh bluh. But I didn't get any Exception so far.
But when I tried to change my program into Dispatcher-driven mode, I encountered a couple of problems. I settled them, so I'd like to share it here.
First, nearly all UI elements are derived from DispatcherObject, then someUIElement.Dispatcher gets the singleton Dispatcher object. Since my program uses MVVM, I cannot get UIElements easily in ViewModel layer, I use Application.Current.Dispatcher instead
eventually.
Then your code should look like this:
public(private) delegate void UpdateViewDelegate(Param1 param1, Param2 param2...);
public(private) void UpdateView(Param1 param1, Param2 param2...) { ... }
YourOperationMethod()
{
Application.Current.Dispatcher.BeginInvoke(new UpdateViewDelegate(UpdateView), param1, param2, ...);
}
Then it works.
BeginInvoke works asynchronously. Invoke works synchronously. Any other usages, see also other articles by searching 'WPF Dispatcher'.
如果你搜索过'WPF Dispatcher',你就一定知道为什么更新UI时要用Dispatcher(System.Windows.Threading.Dispathcer)而不用Thread。好像是说UI上只有一个单线程操作,如果多线程更新会有异常,但我没见过这个异常长啥样。
但是当我试着把我的程序改成用Dispatcher时,遇到了一些问题,最终解决了,在这里分享下。
几乎所有的UI Elements都是继承自DispatcherObject的,所以,只要你有一个someUIElement,你就可以someUIElement.Dispatcher拿到这个全局唯一的Dispatcher对象。因为我的程序使用了MVVM,所以我在ViewModel里拿UIElements不方便,最后我用Application.Current.Dispatcher拿到的。
然后你的程序就应该看起来是这样的:
public(private) delegate void UpdateViewDelegate(Param1 param1, Param2 param2...);
public(private) void UpdateView(Param1 param1, Param2 param2...) { ... }
YourOperationMethod()
{
Application.Current.Dispatcher.BeginInvoke(new UpdateViewDelegate(UpdateView), param1, param2, ...);
}
这样就OK了。
BeginInvoke是异步的. Invoke是同步的. 如果有其它问题就搜索 'WPF Dispatcher'.