[ACCEPTED]-SynchronizationContext.Post to UI Method-multithreading

Accepted answer
Score: 19

You need a delegate of type SendOrPostCallback. Which 6 is pretty awkward, it only takes a single 5 argument of type object. You definitely ought 4 to look at the Task<> class available 3 in .NET 4 to make this easier. Or use a 2 lambda, like this:

        string conn_name = "foo";
        uiContext.Post(new SendOrPostCallback((o) => {
            updateConnStatus(conn_name, true);
        }), null);

The code between the { braces 1 } executes on the UI thread.

Score: 7

Typically you are creating instances of 5 your types (e.g. ViewModels) on the UI thread, so 4 you can just save the SynchronizationContext 3 or the TaskScheduler (preferable IMHO) to 2 a private field and then compare it when 1 needed...

private readonly SynchronizationContext _syncContext = SynchronizationContext.Current;
private readonly TaskScheduler _scheduler = TaskScheduler.Current;

void OnSomeEvent(object sender, EventArgs e)
    if (_syncContext != SynchronizationContext.Current)
        // Use Send if you need to get something done as soon as possible.
        // We'll be polite by using Post to wait our turn in the queue.
        _syncContext.Post(o => DoSomething(), null);
    // Call directly if we are already on the UI thread

void OnSomeOtherEvent(object sender, MyEventArgs e)
    var arg1 = e.Arg1; // "Hello "
    var arg2 = e.Arg2; // {"World", "!"};

    // Process args in the background, and then show the result to the user...
    // NOTE: We don't even need to check the context because we are passing
    // the appropriate scheduler to the continuation that shows a MessageBox.

    Task<string>.Factory.StartNew(() => ReturnSomething(arg1, arg2))
        .ContinueWith(t => MessageBox.Show(t.Result), _scheduler);

void DoSomething() { MessageBox.Show("Hello World!"); }

string ReturnSomething(string s, IEnumerable<string> list)
    return s + list.Aggregate((c, n) => c + n);

More Related questions