我有一个Winforms exe,从菜单中我启动一个运行缓慢的过程作为任务。获取数据然后显示对话框大约需要30秒。通常它不再返回。我捕获异常,日志中没有任何内容,所以我知道它运行正常。表单永远不会出现,似乎没有CPU时间占用。然而,我在调试器中运行它并逐步执行代码,它工作正常。偶尔它似乎可以在更快的PC上运行。怎么了?
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
{
await Task.Run(() =>
{
LaunchForm();
});
}
}
private async void LaunchForm()
{
try
{
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
答案 0 :(得分:1)
请改为:
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e)
{
if (!GetClient()) return;
await LaunchForm();
}
private async Task LaunchForm()
{
try
{
var inPlayView = new InPlayView();
await inPlayView.GetData();
inPlayView.ShowDialog();
}
catch (Exception ex)
{
Logger.LogMessage(ex.ToString());
}
}
您不希望Task.Run()
用于已经异步的方法,并且作为一般规则,async void
对于事件处理程序仅是可以的,因此不是{{1方法。
同样正如评论指出的那样,LaunchForm()
将任务排队到ThreadPool,因此它将最终脱离UI线程。
答案 1 :(得分:0)
我在我的一个项目中使用了异步/等待,我无法想出在任务中执行ShowDialog
的原因。不确定这是否有效,但您可能想稍微改变一下流量。这应该使它更加一致并且可能更容易调试。
private async void inPlayRecordToolStripMenuItem_Click(object sender, EventArgs e) {
if (!GetClient()) {
return;
}
var playView = await LaunchForm();
if (playView != null) {
playView.ShowDialog();
}
}
private async Task<InPlayView> LaunchForm() {
try {
var inPlayView = new InPlayView();
await inPlayView.GetData();
return inPlayView;
} catch (Exception ex) {
// do cleanup of view if needed
Logger.LogMessage(ex.ToString());
return null;
}
}