从后台线程更新UI
这只是一个奇怪的问题。 哪一个是从另一个线程更新UI的最佳方式。 首先,这一个:
private delegate void MyDelegateMethod(); void MyMethod() { if (unknowncontrol.InvokeRequired) { this.BeginInvoke(new MyDelegateMethod(MyMethod)); return; } unknowncontrol.property = "updating!"; }
另一方面:
Invoke((System.Threading.ThreadStart)delegate() { unknowncontrol.property = "updating!"; });
或者,有更好的方法吗?
当然这是针对WinForms的,对于WPF来说是调度员。 WPF的代码如何?
我问,’因为,过去我在使用上述两个选项从引发的事件更新UI时遇到了错误。 类似的错误:“没有可用的源代码”。 我假设我们所有人都见过他们:D。
感谢,并有一个愉快的一天!
查看Roy Osherove的博客文章: http ://osherove.com/blog/2006/3/1/the-3-ways-to-create-a-thread-safe-gui-with-net-20-with -one.html
delegate void Func(T t); Func del = delegate { // UI Code goes here }; Invoke(del);
我通常使用第一个模型,但这只是因为我发现它更清晰。 这两者之间并没有真正有效的区别。
我认为最好的方法是设置ui-element属性绑定到的CLR属性。
第一个方法(BeginInvoke)确保UI更新代码在创建控件的同一线程上执行。 第二种方法没有。 让所有UI更新代码在同一个线程上执行可以避免很multithreading问题,并允许您使用不一定是线程安全的控件。
默认的Action委托在90%的时间内工作:
private void Log(String value) { // Verify that we're on the same thread if (textBox1.InvokeRequired) { // We're not on the same thread - Invoke the UI thread textBox1.Invoke(new Action(Log), value); return; } // We're on the same thread - Update UI textBox1.Text += value + "\r\n"; } private void OnSomethingHappened() { Log("Something happened!"); }
使用[Dispatcher.Invoke(DispatcherPriority,Delegate)]从另一个线程或后台更改UI。
第1步 。 使用以下命名空间
using System.Windows; using System.Threading; using System.Windows.Threading;
第2步 。 将以下行放在需要更新UI的位置
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { //Update UI here }));
句法
[BrowsableAttribute(false)] public object Invoke( DispatcherPriority priority, Delegate method )
参数
priority
键入:
System.Windows.Threading.DispatcherPriority
相对于Dispatcher事件队列中的其他挂起操作的优先级,将调用指定的方法。
method
键入:
System.Delegate
不带参数的方法的委托,该方法被推送到Dispatcher事件队列。
回报价值
键入:
System.Object
来自调用的委托的返回值,如果委托没有返回值,则返回null。
版本信息
自.NET Framework 3.0起可用