You must use Dispatcher .
You can create a class that will contain the dispatcher created in the main thread, and enter it through your container into any class running in the background thread that should interact with your main thread.
public interface IUiDispatcher { Dispatcher Dispatcher { get; } } public class UiDispatcher : IUiDispatcher { public UiDispatcher() { if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA && !Thread.CurrentThread.IsBackground && !Thread.CurrentThread.IsThreadPoolThread) { this.Dispatcher = Dispatcher.CurrentDispatcher; } else { throw new InvalidOperationException("Ui Dispatcher must be created in UI thread"); } } public Dispatcher Dispatcher { get; set; } } public class ExecutedOnABackgroundThread { IUiDispatcher uidispatcher; public ExecutedOnABackgroundThread(IUiDispatcher uidispatcher) { this.uidispatcher = uidispatcher; } public void Method() {
Create an instance of UiDispatcher at a point where you are sure that you are in the user interface stream, for example, during the initialization of your application. Using the dependency injection container, make sure that only one instance of this class will be created and added to any other class that requires it, and use it to create / manage user interface components.
I chose the code to check if the UiDispatcher constructor is UiDispatcher in the main thread from this answer .
The fact is that you cannot use something created in another thread in the user interface thread. Thus, you need your background thread to be delegated to the main user interface thread, in which the user interface materials are involved.
Guillaume
source share