在主机进程结束之前,ContinueWith()不会执行

时间:2013-10-01 20:14:56

标签: c# wpf multithreading .net-4.0 task-parallel-library

我们的团队遇到了一个问题,即在主持人进程关闭之前ContinueWith()无法运行。例如,下面的代码已经在生产中运行了一年。但是,既然我们已经开始使用我们框架的更新版本,那么我们就遇到了这个问题。

运行此代码时,this.Sites = GetViewableSites();会运行,然后在调试时不会发生任何其他情况。点击F10后,调试器返回UI。只有在用户关闭UI后,ContinueWith()才会执行。

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);
});

为了完整性,这里是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;
    }

任何想法会导致什么?我们可以说罪魁祸首是我们的框架,它可能是,但我们无法弄清楚这是怎么发生的。为了解决这个问题,我们停止使用ContinueWith()并将所有代码放在第一部分/任务中。

修改

也许这是一个错误?类似的问题here虽然与Console.ReadKey()有关。

编辑2 - 调用GetViewableSites()后立即调用堆栈

  

未标记> 6324 6工人线程工作者   线程Acme.Mes.Apps.Derating.ViewModels.Controls.GlobalTabControlViewModel.Initialize.AnonymousMethod__9正常                         Acme.Mes.Apps.Derating.ViewModels.dll!Acme.Mes.Apps.Derating.ViewModels.Controls.GlobalTabControlViewModel.Initialize.AnonymousMethod__9()   361行                         Acme.Mes.Client.dll!Acme.Mes.Client.Mvvm.MvvmTools.ViewModelBase.PerformBusyAction.AnonymousMethod__c()   494行+ 0xe字节
                        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(对象   obj)+ 0x15字节
                        mscorlib.dll中!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext   executionContext,System.Threading.ContextCallback回调,对象   state,bool preserveSyncCtx)+ 0xa7 bytes
                        mscorlib.dll中!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext   executionContext,System.Threading.ContextCallback回调,对象   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字节
                        mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()+ 0x149   字节
                        mscorlib.dll中!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()   + 0x5字节
                        [原生于管理过渡]

1 个答案:

答案 0 :(得分:0)

尝试使用调度程序访问IsBusy和BusyMessage。

Dispatcher.BeginInvoke((Action) (() =>
    {
        this.IsBusy = false;
        this.BusyMessage = String.Empty;
    }));