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