C#Thread UI被阻止了| WebRequest.Create的可能原因?

时间:2017-09-01 14:50:27

标签: c# multithreading asynchronous

我目前遇到此问题,阻止我的UI线程。我知道它发生在以下功能中:

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 个答案:

答案 0 :(得分:3)

由于WebRequest.Create在内部使用Dns.GetHostByName这是一种阻止方法(有时非常慢),因此可以阻止您的代码。

一个简单的解决方法是创建一个任务并对其进行授权

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

答案 1 :(得分: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 :(得分:-1)

您可以使用

将任何代码转换为异步代码
Task.Run(()=>{
  //any code here...
});

但是我认为只要您的入口方法是异步的,那么下面的所有内容都会在异步中运行,并引用调用该方法的代码。

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

应该在不阻止你的UI的情况下运行,因为你不应该将everthing转换为异步。

请同时检查你打电话给这个&#34;功能&#34;你在那边使用async / await。如果你有resharper,那通常会告诉你在这种情况下你何时缺少异步/等待,因为没有它你可以同步调用你的方法。