From UI (thread1) I want to create a progress UI(thread2). Progress UI creates a task in thread3 and waits for its completion.
The task(thread3) completes and invoke closing of progress UI which must be executed in thread2.
For closing operation I use AsyncOperationManager to capture context of thread2 and then execute POST method from thread4.
But closing always happens from some another thread.
All the code below is from ProgressWindows class.
_currentTask = new Progress<double>(Close); // I call this in progress UI constructor.
// This is invoked in constructor of Progress class which is used inside ProgressWindow.
_asyncOperation = AsyncOperationManager.CreateOperation(null);
public static void Run2(Action action)
{
Debug.WriteLine(":: Run2 in thread: {0}", Thread.CurrentThread.ManagedThreadId);
var th = new Thread(_ =>
{
Debug.WriteLine(":: StartNew in thread: {0}", Thread.CurrentThread.ManagedThreadId);
var progress = new ProgressWindow();
progress.Run(action);
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
public void Run(Action action)
{
Debug.WriteLine(":: Run in thread: {0}", Thread.CurrentThread.ManagedThreadId);
SetupProgressBar();
RunTask(action);
ShowDialog();
}
private void RunTask(Action action)
{
Task.Factory.StartNew(action).ContinueWith(_ => _currentTask.OnCompleted(null));
}
private void Close(object state)
{
Debug.WriteLine(":: Close in thread: {0}", Thread.CurrentThread.ManagedThreadId);
Hide();
Close();
}
The question is:
private void RunTask(Action action)
{
Task.Factory.StartNew(action).ContinueWith(_ => _currentTask.OnCompleted(null));
}
You see, _currentTask.OnCompleted(null) is invoked from another thread, but _currentTaskof type Progress uses context captured in the UI thread, but OnCompletedis always invoked from another thread other than UI thread. Why? It must be in the same context.
Update 1:
Mixing System.Threading.SynchronizationContext with System.Windows.Form.WindowsFormsSynchronizationContext and System.Windows.Threading.DispatcherSynchronizationContext
ContinueWithfrom a background thread. Why would you assume it would marshal it to the UI thread? - Yuval ItzchakovAsyncOperationManager. - Yuval Itzchakov