为什么只有当MethodTest退出时,action才会被触发

本文关键字:action MethodTest 退出 为什么 | 更新日期: 2023-09-27 18:02:45

action.Invoke()将不会调用"action" action直到MethodTest退出!

     private void MethodTest(string query)
     {
        try
        {
            var webClient = new WebClient();
            string webContent = string.Empty;
            int index;
            Action action = async delegate()
            {
                webContent = await webClient.DownloadStringTaskAsync(url);
                //Add break point above
            };
            action.Invoke();
            index = webContent.IndexOf("<div class='"detName'">");
            // some code here
        }
        catch (WebException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

注意:这将工作得很好!

     private async void MethodTest(string query)
     {
        try
        {
            var webClient = new WebClient();
            string webContent = string.Empty;
            int index;
            webContent = await webClient.DownloadStringTaskAsync(url);
            index = webContent.IndexOf("<div class='"detName'">");
            // some code here
        }
        catch (WebException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

为什么只有当MethodTest退出时,action才会被触发

action.Invoke将立即调用委托。然而,委托不会立即完成,因为它是异步的。委托将在MethodTest返回之前调用webClient.DownloadStringTaskAsync,但这是您唯一的保证。特别是,它将在返回之前不会分配webContent(除非您的HTTP请求非常非常快)。

看起来你试图将异步代码封装在同步代码中。我不想说这是"注定要失败",但这肯定不是一项微不足道的努力。

最好的解决方案是允许您的包含方法为async。我在我的MSDN文章中将其描述为"全程异步"。

如果您绝对确定需要从同步代码调用异步代码,那么Stephen Toub对各种方法(直接阻塞、线程池阻塞和嵌套消息循环)有一个很好的概述。在这种情况下没有"最佳实践";每个方法都有缺点和缺陷。