在长 运行 任务期间显示自定义对话框 window
Displaying a custom dialog window during a long-running task
假设我有一个非常简单的 ProgressBar IsIndeterminate=true
:
<Window x:Class="My.Controls.IndeterminateProgressDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="Window"
Width="300" Height="110" ResizeMode="NoResize" Topmost="True"
WindowStartupLocation="CenterScreen" WindowStyle="None">
<Grid>
<ProgressBar Width="200" Height="20" IsIndeterminate="True" />
</Grid>
</Window>
我想在可能需要一段时间的任务中显示此对话框。我不关心进度(我无法确定),我只是想通知用户我做了一些可能需要几秒钟的事情。
public void GetResult()
{
string result = DoWhileShowingDialogAsync().Result;
//...
}
private async Task<string> DoWhileShowingDialogAsync()
{
var pd = new IndeterminateProgressDialog();
pd.Show();
string ret = await Task.Run(() => DoSomethingComplex()));
pd.Close();
return ret;
}
然而 UI 只是无限地冻结并且任务似乎永远不会 return。问题不在 DoSomethingComplex() 中,如果我 运行 它同步完成,它会毫无问题地完成。我很确定这是因为我误解了 await/async,有人可以指出正确的方向吗?
.Result
这是典型的 UI 线程死锁。使用等待。在调用树中一直使用它。
澄清一下,'use it all the way up the call tree' 意味着您需要从 UI 线程调用它。像这样:
private Task<string> DoWhileShowingDialogAsync()
{
return Task.Run(() => DoSomethingComplex());
}
private string DoSomethingComplex()
{
// wait a noticeable time
for (int i = 0; i != 1000000000; ++i)
; // do nothing, just wait
}
private async void GetResult()
{
pd.Show();
string result = await DoWhileShowingDialogAsync();
pd.Close();
}
假设我有一个非常简单的 ProgressBar IsIndeterminate=true
:
<Window x:Class="My.Controls.IndeterminateProgressDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="Window"
Width="300" Height="110" ResizeMode="NoResize" Topmost="True"
WindowStartupLocation="CenterScreen" WindowStyle="None">
<Grid>
<ProgressBar Width="200" Height="20" IsIndeterminate="True" />
</Grid>
</Window>
我想在可能需要一段时间的任务中显示此对话框。我不关心进度(我无法确定),我只是想通知用户我做了一些可能需要几秒钟的事情。
public void GetResult()
{
string result = DoWhileShowingDialogAsync().Result;
//...
}
private async Task<string> DoWhileShowingDialogAsync()
{
var pd = new IndeterminateProgressDialog();
pd.Show();
string ret = await Task.Run(() => DoSomethingComplex()));
pd.Close();
return ret;
}
然而 UI 只是无限地冻结并且任务似乎永远不会 return。问题不在 DoSomethingComplex() 中,如果我 运行 它同步完成,它会毫无问题地完成。我很确定这是因为我误解了 await/async,有人可以指出正确的方向吗?
.Result
这是典型的 UI 线程死锁。使用等待。在调用树中一直使用它。
澄清一下,'use it all the way up the call tree' 意味着您需要从 UI 线程调用它。像这样:
private Task<string> DoWhileShowingDialogAsync()
{
return Task.Run(() => DoSomethingComplex());
}
private string DoSomethingComplex()
{
// wait a noticeable time
for (int i = 0; i != 1000000000; ++i)
; // do nothing, just wait
}
private async void GetResult()
{
pd.Show();
string result = await DoWhileShowingDialogAsync();
pd.Close();
}