Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report for Bug 57544 on
GitHub or Developer Community if you have new
information to add and do not yet see a matching new report.
If the latest results still closely match this report, you can use the
In special cases on GitHub you might also want the comments:
GitHub Markdown with public comments
Description of Problem:
BackgroundWorker progress and completion events are NOT called on correct threads.
Steps to reproduce the problem:
1. Create BackgroundWorker on main thread with event handlers
2. Start it
Progress and completion event handlers are called on threadpool threads.
Progress and completion event handlers should be called on main (UI) thread when worker created and started on UI thread.
How often does this happen?
Installation UUID: 34e7037c-bfa4-44c3-b92a-cab81ac3fdbf
Mono 188.8.131.52 (2017-02/5077205 Thu May 25 09:19:18 UTC 2017) (64-bit)
GTK+ 2.24.30 (Ambiance theme)
Build information unavailable
Linux ubuntu 4.8.0-54-generic #57~16.04.1-Ubuntu SMP Wed May 24 16:22:28 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Here's the main part of the program (modified HelloWorldGtk):
public static void Main (string args)
MainWindow win = new MainWindow ();
private static bool StartTask()
System.Diagnostics.Debug.WriteLine("CREATE: " + Thread.CurrentThread.ManagedThreadId);
var worker = new BackgroundWorker ();
worker.WorkerReportsProgress = true;
worker.DoWork += Worker_DoWork;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
private static void Worker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
System.Diagnostics.Debug.WriteLine("COMPLETE: " + Thread.CurrentThread.ManagedThreadId);
private static void Worker_ProgressChanged (object sender, ProgressChangedEventArgs e)
System.Diagnostics.Debug.WriteLine ("PROGRESS!: " + Thread.CurrentThread.ManagedThreadId);
private static void Worker_DoWork (object sender, DoWorkEventArgs e)
System.Diagnostics.Debug.WriteLine ("DOING WORK: " + Thread.CurrentThread.ManagedThreadId);
var worker = e.Argument as BackgroundWorker;
UPDATE: I have some old notes in source code elsewhere (written in MonoMac -- not tested in Xamarin.Mac) that indicate the same problem may exist in MonoMac. That code was written back in 2014 - things have changed a bit since then.
The codebase using BackgroundWorker *ALWAYS* creates the objects in the UI thread.
The BackgroundWorker needs a valid SynchronizationContext to synchronize with the UI thread, but Gtk# 2 does not register its own context (this has been added for Gtk# 3 only: https://github.com/mono/gtk-sharp/commit/8e07e7d2257b185866dedfda9cbf32b2e00cd3ee). You could create your own GLibSynchronizationContext, or use a different synchronization technique (i.e. synchronize manually with Gtk.Application.Invoke inside your handlers)
Ah OK -- thanks for the confirmation. I'd already implemented the Application.Invoke workaround in my abstraction layer. :D
When I circle back round to MonoMac/Xamarin.Mac testing of my app, I'll check / confirm behaviors there.