async/await vs ContinueWith

avo*_*avo 3 c# winforms task-parallel-library async-await

我认为几乎所有使用的代码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");
Run Code Online (Sandbox Code Playgroud)

怎么办async/await

Dan*_*ant 7

您可以将中间部分拆分为辅助异步方法:

        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");
        }
Run Code Online (Sandbox Code Playgroud)

这揭示了原始代码的问题,即继续任务永远不会被"等待"(在原始上下文中给出一个ContinueWith),这意味着它抛出的任何异常都将是未处理的.理想情况下,你将它存储在某个地方的Task变量中,并决定一个好的地方等待它并处理它抛出的任何异常.


一个简短的说明:

无论使用哪种方法,如果用户在第二个过去之前关闭消息框,{ENTER}将被发送到关闭后具有焦点的任何控件,这可能导致意外的操作,例如在任何活动的窗口上按下默认按钮在启动消息框之前.如果打算创建一个自动消失但可以提前解散的弹出窗口,您可能只想创建一个提供所需行为的自定义窗口.