2017-09-01 37 views
3

我目前有問題,那是阻止我的UI線程。我知道這是在下面的函數發生的事情:C#線程UI被阻止|可能的原因WebRequest.Create?

public async Task<string> function(string username, string password, string handle) 
{ 
    try 
    { 
     string finalStr; 

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://url.com"); 
     request.CookieContainer = cookie; 
     request.AllowAutoRedirect = true; 

     var response = await request.GetResponseAsync(); 

     string str = new StreamReader(response.GetResponseStream(), Encoding.UTF8).ReadToEnd(); 

     string str2 = this.getToken(str, "_token\" value=\"", "\">", 0); 
     string[] textArray1 = new string[] { "postVariables=" + str2 }; 

     HttpWebRequest httpWebRequest_0 = (HttpWebRequest)WebRequest.Create("https://url.com"); 
     httpWebRequest_0.CookieContainer = cookie; 
     httpWebRequest_0.Method = "POST"; 
     httpWebRequest_0.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; 
     httpWebRequest_0.Referer = "https://twitter.com/settings/account"; 
     httpWebRequest_0.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"; 
     httpWebRequest_0.AllowAutoRedirect = true; 
     httpWebRequest_0.ContentType = "application/x-www-form-urlencoded"; 

     byte[] bytes = Encoding.ASCII.GetBytes(string.Concat(textArray1)); 
     httpWebRequest_0.ContentLength = bytes.Length; 

     Stream requestStream = await httpWebRequest_0.GetRequestStreamAsync(); 
     await requestStream.WriteAsync(bytes, 0, bytes.Length); 

     var response2 = await httpWebRequest_0.GetResponseAsync(); 

     using (StreamReader reader = new StreamReader(response2.GetResponseStream())) 
     { 
      finalStr = reader.ReadToEnd(); 
     } 

     if (finalStr.Contains(handle)) 
     { 
      return "success"; 
     } 
     else 
     { 
      requestStream.Close(); 
      return "error"; 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

我相信這是這部分功能:

HttpWebRequest httpWebRequest_0 = (HttpWebRequest)WebRequest.Create("https://url.com"); 

我怎麼可以創建一個async WebRequest.Create?還有什麼我做錯了嗎?

我欣賞任何形式的幫助和建議。

回答

3

由於WebRequest.Create在內部使用Dns.GetHostByName這是一種阻塞方法(有時非常慢),因此您的代碼可能會在此時被阻塞。

簡單的解決方法,可以創建任務和awating它

HttpWebRequest request = await Task.Run(()=> WebRequest.Create("https://google.com") as HttpWebRequest); 
+0

我認爲你複製並粘貼了錯誤的鏈接* Dns.GetHostByName * –

+0

@ScottChamberlain它是* Dns.GetHostByName *被引用的地方。不是它的代碼。 (也許我應該提到哪個使用* gethostname * API) –

+0

該鏈接將我帶到Internal.cs中的屬性WebRequestPrefixElement.Creator。在'NclUtilities.GetLocalHost'函數中禁用的'else //!FEATURE_PAL'節中,除了Internal.cs中的任何地方,我沒有看到Dns.GetHostByName被調用。 –

1

我建議切換到HttpClient作爲推薦的客戶端前進。 (感謝提醒Erik)

這將需要一些更新以適應您的需求,但它是進行轉換的起點。

  using (var client = new HttpClient(new HttpClientHandler 
      { 
       AllowAutoRedirect = true, 
       CookieContainer = new CookieContainer() 
      })) 
      { 
       client.DefaultRequestHeaders.Clear(); 
       client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")); 
       client.DefaultRequestHeaders.Referrer = new Uri("https://twitter.com/settings/account"); 
       client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"); 

       // Get 
       var result = await client.GetAsync(new Uri("")); 
       if (result.IsSuccessStatusCode) 
       { 
        var content = await result.Content.ReadAsStringAsync(); 
       } 
       else 
       { 
        Console.WriteLine($"{result.StatusCode}: {await result.Content.ReadAsStringAsync()}"); 
       } 

       // Post 
       var post = await client.PostAsync("Uri", new StringContent("could be serialized json or you can explore other content options")); 
       if (post.IsSuccessStatusCode) 
       { 
        var contentStream = await post.Content.ReadAsStreamAsync(); 
        var contentString = await post.Content.ReadAsStringAsync(); 
       } 
      } 
+2

實際上[HttpClient的](https://msdn.microsoft.com/en-us/library/system.net.http.httpclient( v = vs.110).aspx)是新的框架Http客戶端前進。 –

-1

您可以通過使用

Task.Run(()=>{ 
    //any code here... 
}); 

任何一段代碼到異步代碼轉換,但只要你的輸入方法是異步然後在一切都在異步運行參考代碼中調用我認爲該方法。

public async Task<string> function(string username, string password, string handle) 

因此應該運行而不會阻塞您的UI因爲您不希望將everthing轉換爲異步。

還請檢查當你調用這個「功能」,你在那裏使用異步/等待。如果你擁有resharper,那麼通常會告訴你什麼時候你在這種情況下缺少異步/等待,因爲如果沒有,你可以同步調用你的方法。