0

Usually we invoke on UI thread that way :

myControl.Invoke((MethodInvoker)delegate() { Foo(); });

Are they any way to do it without any control instance ? I mean something like this :

System.Windows.Forms.Thread.Invoke(...);


Solution Solution given by dcastro, using WindowsFormsSynchronizationContext. Here is a really simple example in a form :

public partial class FrmFoo : Form
{
    SynchronizationContext uiThread;

    public void FrmFoo()
    {
        // Needs to assign it from somewhere in the UI thread (in constructor for example)
        uiThread = WindowsFormsSynchronizationContext.Current;
    }

    void AsyncBar()
    {
        uiThread.Send(delegate(object state)
        {
            // UI Cross-Thread dangerous manips allowed here
        }, null);
    }
}
56ka
  • 1,463
  • 1
  • 21
  • 37

2 Answers2

1

You can use the current WindowsFormsSynchronizationContext (available since .NET 2.0)

System.Threading.SynchronizationContext.Current.Post(delegate, state);

You should grab a reference to the context from your UI thread, and make it accessible to your other threads, which can then use it to execute code on the UI thread.

This is equivalent to BeginInvoke. For a Invoke equivalent, use the Send method instead.

dcastro
  • 66,540
  • 21
  • 145
  • 155
  • This solution will not work when called from a worker thread. – Gusdor Dec 19 '13 at 13:36
  • @Gusdor It won't but the `Current` instance can be catched from the right thread and the "WindowsForms(..)" protects to catch an other context. I update my post with solution example – 56ka Dec 19 '13 at 13:46
  • @56ka Absolutely! If the answer would make that clear, I would not have felt inclined to comment upon it. – Gusdor Dec 19 '13 at 13:50
0

Use SynchronizationContext and it's Post method

var sCon=SynchronizationContext.Current;
        sCon.Post(new SendOrPostCallback((o) => {
            //do your stuffs
        }), null);

SynchronizationContext is just an abstraction, one that represents a particular environment you want to do some work in. As an example of such an environment, Windows Forms apps have a UI thread (while it’s possible for there to be multiple, for the purposes of this discussion it doesn’t matter), which is where any work that needs to use UI controls needs to happen. For cases where you’re running code on a ThreadPool thread and you need to marshal work back to the UI so that this work can muck with UI controls, Windows Forms provides the Control.BeginInvoke method. You give a delegate to a Control’s BeginInvoke method, and that delegate will be invoked back on the thread with which that control is associated.

S.N
  • 4,910
  • 5
  • 31
  • 51
  • From msdn: `Gets the synchronization context for the current thread.` When called from a worker thread, this solution will not work - `SynchronizationContext.Current` will return `null` or worse, the default context. – Gusdor Dec 19 '13 at 13:38
  • This is the first step, thank you – 56ka Dec 19 '13 at 13:56