Our team has been having an issue where ContinueWith()
won't run until the host process is shutting down. For example, the code below has been running just fine in production for a year. But since we've started using newer versions of our framework, we've had this issue.
When running this code, this.Sites = GetViewableSites();
runs and then nothing else happens when debugging. After hitting F10
, the debugger returns to the UI. Only after the user closes the UI does the ContinueWith()
execute.
this.PerformBusyAction(() =>
{
this.Sites = GetViewableSites();
}, ViewModelResource.LoadingForm)
.ContinueWith(originatingTask =>
{
// ** This doesn't execute until the user closes the UI **
if (originatingTask.Exception == null)
{
PerformPostSuccessfulInitialization();
return;
}
PerformPostUnsuccessfulInitialization(originatingTask.Exception.InnerExceptions);
});
For completeness, here is PerformBusyAction()
:
protected Task PerformBusyAction(Action action, string busyMessage)
{
this.BusyMessage = busyMessage;
this.IsBusy = true; // Let the UI know we're busy, so it can display a busy indicator
var task = Task.Factory.StartNew(() =>
{
try
{
action();
}
finally
{
this.IsBusy = false;
this.BusyMessage = String.Empty;
}
});
return task;
}
Any idea what would cause this? We can say the culprit is our framework, and it may be, but we haven't been able to figure out how this can possibly happen. To get around the issue, we just stopped using ContinueWith()
and put all the code in the first section/task.
Edit
Perhaps this is a bug? There is a similar issue here, although it's with Console.ReadKey()
.
Edit 2 - Call stack immediately after calling GetViewableSites()
Not Flagged > 6324 6 Worker Thread Worker Thread Acme.Mes.Apps.Derating.ViewModels.Controls.GlobalTabControlViewModel.Initialize.AnonymousMethod__9 Normal Acme.Mes.Apps.Derating.ViewModels.dll!Acme.Mes.Apps.Derating.ViewModels.Controls.GlobalTabControlViewModel.Initialize.AnonymousMethod__9() Line 361
Acme.Mes.Client.dll!Acme.Mes.Client.Mvvm.MvvmTools.ViewModelBase.PerformBusyAction.AnonymousMethod__c() Line 494 + 0xe bytes
mscorlib.dll!System.Threading.Tasks.Task.InnerInvoke() + 0x49 bytes
mscorlib.dll!System.Threading.Tasks.Task.Execute() + 0x2e bytes
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) + 0x15 bytes
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) + 0xcb bytes
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) + 0xb3 bytes
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() + 0x7 bytes
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() + 0x149 bytes
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() + 0x5 bytes
[Native to Managed Transition]