Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run code on UI thread without control object present

I currently trying to write a component where some parts of it should run on the UI thread (explanation would be to long). So the easiest way would be to pass a control to it, and use InvokeRequired/Invoke on it. But I don't think that it is a good design to pass a control reference to a "data/background"-component, so I'm searching for a way to run code on the UI thread without the need of having a control available. Something like Application.Dispatcher.Invoke in WPF...

any ideas, thx Martin

like image 963
Martin Moser Avatar asked Jan 19 '09 10:01

Martin Moser


1 Answers

First, in your form constructor, keep a class-scoped reference to the SynchronizationContext.Current object (which is in fact a WindowsFormsSynchronizationContext).

public partial class MyForm : Form {
    private SynchronizationContext syncContext;
    public MyForm() {
        this.syncContext = SynchronizationContext.Current;
    }
}

Then, anywhere within your class, use this context to send messages to the UI:

public partial class MyForm : Form {
    public void DoStuff() {
        ThreadPool.QueueUserWorkItem(_ => {
            // worker thread starts
            // invoke UI from here
            this.syncContext.Send(() =>
                this.myButton.Text = "Updated from worker thread");
            // continue background work
            this.syncContext.Send(() => {
                this.myText1.Text = "Updated from worker thread";
                this.myText2.Text = "Updated from worker thread";
            });
            // continue background work
        });
    }
}

You will need the following extension methods to work with lambda expressions: http://codepaste.net/zje4k6

like image 172
SandRock Avatar answered Sep 29 '22 06:09

SandRock