C# 阻塞UI线程dosen';t呈现其他窗口的UI组件

C# 阻塞UI线程dosen';t呈现其他窗口的UI组件,c#,wpf,multithreading,C#,Wpf,Multithreading,在我的应用程序中,我有一个场景,当我执行一个操作时,我需要阻止UI线程。当它被阻止时,我还有一个窗口需要在UI被阻止时显示一条消息,上面写着“正在执行操作,请稍候”。问题是窗口会显示,但它从不显示消息。请帮忙。甚至都没用。它只是轻轻地显示了信息 注: 我不希望该方法是异步的,因为我想在UI运行时阻止它 我不想说ShowDialog(),因为它只是在那里阻塞 CommandRunningWindow具有绑定到textblock的string(message)类型的依赖项属性。不能同时在同一线程上阻

在我的应用程序中,我有一个场景,当我执行一个操作时,我需要阻止UI线程。当它被阻止时,我还有一个窗口需要在UI被阻止时显示一条消息,上面写着“正在执行操作,请稍候”。问题是窗口会显示,但它从不显示消息。请帮忙。甚至都没用。它只是轻轻地显示了信息

注:

  • 我不希望该方法是异步的,因为我想在UI运行时阻止它
  • 我不想说ShowDialog(),因为它只是在那里阻塞
    CommandRunningWindow具有绑定到textblock的string(message)类型的依赖项属性。

    不能同时在同一线程上阻止和显示消息

    您应该做的是在后台线程上执行长时间运行的操作—最简单的方法是启动一个—并在UI线程上显示消息。您仍然可以禁用该窗口。只需确保不要触摸执行长时间运行操作的后台线程上的UI

    private void ViewModel_PerformPrimeAction(InstrumentAction Action)
    {
        bool abort = false;
    
        CommandRunningWindow cmdDialog = null;
        if (Action == InstrumentAction.Prime)
        {
            if (Xceed.Wpf.Toolkit.MessageBox.Show((string)TryFindResource("ConfirmPrimeInstrument"),
                ApplicationSettingsViewModel.Instance.ProductName, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                return;
    
            this.IsEnabled = false;
            //This below line never shows the message.
            cmdDialog = ShowCommandWindow(ViewModelsHelper.GetResourceString("PerformingPrime"));
        }
        UIUtils.OverrideCursor = System.Windows.Input.Cursors.Wait;
    
        Task.Factory.StartNew(() =>
        {
            // This operation takes 10 seconds
            QXInstrumentViewModel.Instance.Prime(() => { if (abort) throw new RunAbortedException(null); });
        })
        .ContinueWith(task =>
        {
            if (task.IsFaulted)
            {
                if (task.Exception != null && task.Exception.GetBaseException() is RunAbortedException)
                {
                    var message = QXInstrumentViewModel.ToErrorCode(ex);
                    TokenSource = new System.Threading.CancellationToken(true);
                    if (message != null)
                    {
                        errorMessage = string.Format((string)TryFindResource("CompletePrimeInstrumentWithError"), Convert.ToInt32(message), errorMessage);
                    }
                    else
                    {
                        errorMessage = (string)TryFindResource("CompletePrimeInstrumentWithUnknownError");
                    }
                }
                else
                {
                    errorMessage = (string)TryFindResource("CompletePrimeInstrumentAborted");
                }
            }
            cmdDialog?.Close();
            UIUtils.OverrideCursor = null;
            this.IsEnabled = true;
        }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }
    

    不要阻塞UI线程。这只会给你带来麻烦。如果要阻止用户与UI的某个部分交互,请禁用UI的这些部分,不要阻止UI线程。我想阻止UI,但不想阻止UI。听起来你想去游泳而不被淋湿。退一步,再想想。嗯,好吧,我想禁用控件,但问题是,它永远不会停留在当前窗口上。一旦操作完成,即使没有用户操作,它也会切换到另一个选项卡。它是从另一个地方以这种方式实施的。所以我想如果有一个简单的方法,我做了一些类似的事情,不确定这是否是一个理想的方法,如果有人能纠正我。我使方法异步。我增加了等待任务。延迟(100);在显示dalog步骤之后,有什么特别的原因不能弹出一个模态对话框吗?
    private void ViewModel_PerformPrimeAction(InstrumentAction Action)
    {
        bool abort = false;
    
        CommandRunningWindow cmdDialog = null;
        if (Action == InstrumentAction.Prime)
        {
            if (Xceed.Wpf.Toolkit.MessageBox.Show((string)TryFindResource("ConfirmPrimeInstrument"),
                ApplicationSettingsViewModel.Instance.ProductName, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                return;
    
            this.IsEnabled = false;
            //This below line never shows the message.
            cmdDialog = ShowCommandWindow(ViewModelsHelper.GetResourceString("PerformingPrime"));
        }
        UIUtils.OverrideCursor = System.Windows.Input.Cursors.Wait;
    
        Task.Factory.StartNew(() =>
        {
            // This operation takes 10 seconds
            QXInstrumentViewModel.Instance.Prime(() => { if (abort) throw new RunAbortedException(null); });
        })
        .ContinueWith(task =>
        {
            if (task.IsFaulted)
            {
                if (task.Exception != null && task.Exception.GetBaseException() is RunAbortedException)
                {
                    var message = QXInstrumentViewModel.ToErrorCode(ex);
                    TokenSource = new System.Threading.CancellationToken(true);
                    if (message != null)
                    {
                        errorMessage = string.Format((string)TryFindResource("CompletePrimeInstrumentWithError"), Convert.ToInt32(message), errorMessage);
                    }
                    else
                    {
                        errorMessage = (string)TryFindResource("CompletePrimeInstrumentWithUnknownError");
                    }
                }
                else
                {
                    errorMessage = (string)TryFindResource("CompletePrimeInstrumentAborted");
                }
            }
            cmdDialog?.Close();
            UIUtils.OverrideCursor = null;
            this.IsEnabled = true;
        }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
    }