2014-05-09 62 views
1

action.Invoke()将不会调用“操作”操作,直到MethodTest退出!为什么只有在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); 
     } 
    } 
+1

由于我们无法在评论上设置断点,因此当您说“这里”时,是指“在上面的行上”或“在下面的行上”? –

回答

2

action.Invoke将立即调用委托。但是,代表不会立即完成,因为它是异步的。代表将在MethodTest退回之前致电webClient.DownloadStringTaskAsync,但这是您唯一的保证。具体来说,它会在返回之前将而不是赋值为webContent(除非您的HTTP请求真的很快)。

它看起来像你试图在同步代码中包装异步代码。我不想说这是“注定要失败”,但这当然不是一个微不足道的努力。

最好的解决办法是让你的包含方法是async。我在my MSDN article中将其描述为“一路异步”。

如果你绝对相信需要从同步代码中调用异步代码,然后Stephen Toub has a good overview of the various approaches(直接阻断,阻断线程池和嵌套的消息循环)。在这种情况下没有“最佳做法”;每种方法都有缺点和缺陷。

相关问题