Question

Here's the problem: I have an Outlook add-in made with add-in express. It hosts a panel with the only winforms ElementHost, where WPF content is performing. In this WPF control I have a textbox and button. Button click triggers Backgroundworker to load info from database, in 'RunWorkerCompleted' process this data is being put into control. When button is pressed - everything goes normally. But if I catch 'Enter' key press in textbox and then trigger BackgroundWorker - 'RunWorkerCompleted' is being launched not in the main thread, but in a thread pool, and cannot access WPF elements. In both cases BackGroundWorker.RunWorkerAsync() is being called from Main thread, DoWork runs in thread pool, and only in case of enter-key-catch, RunWorkerCompleted also runs in a thread pool.

Was it helpful?

Solution

You've run into a bug in Add-in Express. In some cases Add-in Express event handlers are called with System.Threading.SynchronizationContext.Current set to null. BackgroundWorker use it in RunWorkerAsync method to save the ui context, so that is the problem.

To fix SynchronizationContext you could use the following workaround. Here MyAction is the method where you call RunWorkerAsync from.

var ctx = SynchronizationContext.Current;
if (ctx != null)
{
    MyAction();
}
else
{
    var timer = new DispatcherTimer();
    timer.Tick += (s, a) =>
    {
        MyAction();
        timer.Stop();
        timer = null;
    };
    timer.Interval = TimeSpan.FromMilliseconds(10);
    timer.Start();
}

Another solution would be saving the valid SynchronizationContext.Current value somewhere in a static member and then calling SynchronizationContext.Post in the event handler for the same purpose. I haven't tried this one though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top