Reputation: 1616
To quote Marc Gravell:
///...blah blah updating files
string newText = "abc"; // running on worker thread
this.Invoke((MethodInvoker)delegate {
someLabel.Text = newText; // runs on UI thread
});
///...blah blah more updating files
I'm looking to do this with WPF so can't use the invoke
method. Any thoughts? This Threading stuff is doing my head in :/
MORE DETAIL
I began my new Thread like so
Thread t = new Thread (LoopThread);
t.Start();
t.Join();
But throughout LoopThread
, I want to write to the UI.
UPDATE
Thanks to Jon Skeet for the Dispatcher.Invoke
bit. Seems MethodInvoker
is WinForms also. WPF equivalent?
UPDATE 2
Thanks Adriano for suggesting instead of System.Windows.Forms.MethodInvoker
, using System.Action
.
(You guys were right about the this
parameter confusion, just need to build to remove errors.)
Bus since adding the SimpleInvoke
, now I'm hit with
Extension method must be defined in a non-generic static class
on the line
public partial class MainWindow : Window
Any thoughts?
Upvotes: 1
Views: 331
Reputation: 615
as compromise using SynchronizationContext:
// gui thread
var sc = SynchronizationContext.Current;
// work thread
sc.Post(s =>
{
someLabel.Text = newText
}, null);
Upvotes: 0
Reputation: 812
Continuing from Jon Skeet comment, and you can call your extension like below
DispatcherObject.SimpleInvoke(() => someLabel.Text = newText);
Upvotes: -1
Reputation: 1500345
In WPF, you just use Dispatcher.Invoke
instead of Control.Invoke
.
The DispatcherObject
class (which WPF classes derive from) exposes a Dispatcher
property, so you just need:
Dispatcher.Invoke((Action) delegate {
someLabel.Text = newText; // runs on UI thread
});
If you're using C# 3 or higher (and .NET 3.5 or higher) you might want to add an extension method to DispatcherObject
:
// Make this a new top-level class
public static class DispatcherObjectExtensions
{
public static void SimpleInvoke(this DispatcherObject dispatcherObject,
Action action)
{
dispatcherObject.Dispatcher.Invoke(action);
}
}
So you can just use:
// From within your UI code
this.SimpleInvoke(() => someLabel.Text = newText);
Upvotes: 6