问题
This is just a curious question. Which one is the best way to update UI from another thread. First, this one:
private delegate void MyDelegateMethod();
void MyMethod()
{
if (unknowncontrol.InvokeRequired)
{
this.BeginInvoke(new MyDelegateMethod(MyMethod));
return;
}
unknowncontrol.property = "updating!";
}
On the other hand:
Invoke((System.Threading.ThreadStart)delegate()
{
unknowncontrol.property = "updating!";
});
Or, is there a better way to do this?
Of course this is for WinForms, for WPF there's the dispatcher. How is the code for WPF?
I'm asking, 'cause, in the past I experienced errors when updating UI from a raised event using both of the options above. The kind of error like: "there is no source code available". I assume all of us have seen them :D.
Thanks, and have a nice day!
回答1:
Check out Roy Osherove's blog post on this: 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 t);
Func del = delegate
{
// UI Code goes here
};
Invoke(del);
回答2:
I typically used the first model, but that's only because I found it clearer. There isn't really going to be an effective difference between the two.
回答3:
As i see it the best way is to set a CLR-property to which the ui-element's property is bound to.
回答4:
The first method (BeginInvoke) ensures that the UI update code executes on the same thread that created the control. The 2nd method does not. Having all UI updating code execute on the same thread avoids alot of threading issues and allows you to use controls that are not necessarily thread-safe.
回答5:
The default Action delegate worked 90% of the time:
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<string>(Log), value);
return;
}
// We're on the same thread - Update UI
textBox1.Text += value + "\r\n";
}
private void OnSomethingHappened()
{
Log("Something happened!");
}
回答6:
Use [Dispatcher.Invoke(DispatcherPriority, Delegate)] to change the UI from another thread or from background.
Step 1. Use the following namespaces
using System.Windows;
using System.Threading;
using System.Windows.Threading;
Step 2. Put the following line where you need to update UI
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate
{
//Update UI here
}));
Syntax
[BrowsableAttribute(false)] public object Invoke( DispatcherPriority priority, Delegate method )
Parameters
priority
Type:
System.Windows.Threading.DispatcherPriority
The priority, relative to the other pending operations in the Dispatcher event queue, the specified method is invoked.
method
Type:
System.Delegate
A delegate to a method that takes no arguments, which is pushed onto the Dispatcher event queue.
Return Value
Type:
System.Object
The return value from the delegate being invoked or null if the delegate has no return value.
Version Information
Available since .NET Framework 3.0
来源:https://stackoverflow.com/questions/7959005/update-ui-from-background-thread