【发布时间】:2018-06-29 13:18:14
【问题描述】:
我有两个默认窗口。 我想要一个窗口开始一项工作,以模态(对话框)形式显示另一个窗口(进度指示,但现在不重要),然后在这项工作完成后将其关闭。我有我的实现中存在以下问题:
1) 工作完成后(出现“Completed!”消息框,但也不重要,只是提示),ProgressWindow 不会自动关闭;
2) 如果我通过手动单击红叉将其关闭,则会出现 System.InvalidOperationException 并显示消息“调用线程无法访问此对象,因为不同的线程拥有它。”发生在行
await task;
3) ContinueWith 中的代码实际上是在 Go 方法完成之前执行的 - 为什么?
我怎样才能实现这样的行为?
我的实现:
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
async void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Window w = new ProgressWindow();
var task =
Task
.Run(() => Go())
.ContinueWith(completedTask => w.Close());
w.ShowDialog();
await task; // InvalidOperationException throws
}
async protected void Go()
{
await Task.Delay(500); // imitate some work
MessageBox.Show("Completed!"); // indicate that work has been completed
}
}
}
【问题讨论】:
-
ShowDialog不会阻止吗?如果用户不关闭对话框,您怎么会知道任务已完成?我认为您需要将任务作为参数传递给对话框,并将await传递给某个地方。任务完成后,窗口可以自行关闭。 -
我不明白“将任务传递给对话框”是什么意思。在对话框的代码后面的某处执行任务?.. 但是如果我向后做 - 将对话框传递给任务 - 我可以实现所需的行为。
-
实际上,我认为您的方法(尽管您认为它不起作用)很好。我可能应该对 Peter Bons 的帖子发表评论。我在你的代码和他的代码之间来回切换。
-
我还提出了我自己的解决方案,以实现所需的行为。
-
@KennethK。我的方法也不好,因为 ContinueWith 中的代码实际上是在 Go 完成之前执行的。这很奇怪,我不知道为什么。
标签: c# wpf modal-dialog async-await task