2017-02-26 44 views
0

我有下面的代码是从网站UI封锁任务

private void BeginCreationButton_Click(object sender, RoutedEventArgs e) 
    { 
     //Log("INFO", "Beggining ad creation"); 
     GeneralProgressBar.Visibility = Visibility.Visible; 

     foreach(var ad in ads) 
     { 
      string adUh = string.Empty; 
      string errorMsg = string.Empty; 
      bool error = false; 

      //Task<string> uhFetch = Task<string>.Factory.StartNew(() => GetUhForAdvert()); 
      Task task = Task.Factory.StartNew(() => 
      { 
       HttpWebRequest newPromoRequest = WebRequest.Create("https://www.randomsite.com") as HttpWebRequest; 
       newPromoRequest.CookieContainer = Cookies; 
       newPromoRequest.Method = "GET"; 
       newPromoRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; 
       string uh = string.Empty; 

       HttpWebResponse response = (HttpWebResponse)newPromoRequest.GetResponse(); 

       if (response.StatusCode == HttpStatusCode.OK) 
       { 
        using (Stream s = response.GetResponseStream()) 
        { 
         using (StreamReader sr = new StreamReader(s, Encoding.GetEncoding(response.CharacterSet))) 
         { 
          HtmlDocument doc = new HtmlDocument(); 

          doc.Load(sr); 

          adUh = doc.DocumentNode.SelectNodes("//form")[0].SelectNodes("//input")[0].Attributes[2].Value; 
         } 
        } 
       } 
      }); 

      try 
      { 
       task.Wait(); 
      } 
      catch (AggregateException ae) 
      { 
       ae.Handle((x) => 
       { 
        errorMsg = x.Message + " | " + x.StackTrace; 
        error = true; 

        return error; 
       }); 
      } 

      if (error) 
      { 
       Log("ERROR", errorMsg); 
      } 

      Log("INFO", adUh); 
     } 
    } 

然而得到的数据,而在任务执行时,UI是越来越阻止,但我不知道为什么它的发生。不知道它是流阅读还是HTML处理部分,因为我在没有这两个组件的情况下在我的项目的其他部分使用请求代码,它的作用就像魅力一样。

+4

我猜'task.Wait();'是它的原因。尝试将您的点击方法更改为async('private async void')并使用'await task'。 – Alisson

+0

@阿利森该死的,这么小的改变确实令人惊叹。请添加您的评论作为答案:D – Jhon

+2

@JhonAlx:[这是为什么](http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)。 –

回答

3

不要使用task.Wait();阻止您的UI线程。让你的按钮单击处理异步是这样的:

private async void BeginCreationButton_Click(object sender, RoutedEventArgs e) 
{ 
    // code here... 
} 

...并在您致电:

task.Wait(); 

...这样称呼它:

await task; 

而且,您不需要使用Task.Factory.StartNew,只需使用(HttpWebResponse)await newPromoRequest.GetResponseAsync();并将您的任务的所有代码包装在012中即可简化区块。


编辑:您可以了解有关此主题的详细说明读Stephen Cleary's blog