我认为几乎所有使用的代码ContinueWith
都可以重构async/await
,但这个有点难.我要转换的草图:
// UI unit testing: close the message box in 1s Task.Delay(1000).ContinueWith((t) => { SendKeys.Send("{ENTER}"); }, TaskScheduler.FromCurrentSynchronizationContext()); MessageBox.Show("Hello!"); Debug.Print("continue after a message box");
怎么办async/await
?
您可以将中间部分拆分为辅助异步方法:
private async Task EnterAfterDelay() { await Task.Delay(1000); SendKeys.Send("{ENTER}"); } private void MyMethod() { EnterAfterDelay(); MessageBox.Show("Hello!"); Debug.Print("continue after a message box"); }
这揭示了原始代码的问题,即继续任务永远不会被"等待"(在原始上下文中给出一个ContinueWith),这意味着它抛出的任何异常都将是未处理的.理想情况下,你将它存储在某个地方的Task变量中,并决定一个好的地方等待它并处理它抛出的任何异常.
一个简短的说明:
无论使用哪种方法,如果用户在第二个过去之前关闭消息框,{ENTER}将被发送到关闭后具有焦点的任何控件,这可能导致意外的操作,例如在任何活动的窗口上按下默认按钮在启动消息框之前.如果打算创建一个自动消失但可以提前解散的弹出窗口,您可能只想创建一个提供所需行为的自定义窗口.