简体   繁体   English

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

[英]C# Thread UI is getting blocked | Possible reason WebRequest.Create?

I'm currently having the issue, that something is blocking my UI thread . 我目前遇到了这个问题,有些东西阻止了我的UI线程 I know it is happening in the following function: 我知道它发生在以下功能中:

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);
    }
}

I believe it's this part of the function: 我相信这是功能的这一部分:

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

How could I create a async WebRequest.Create? 我怎么能创建一个async WebRequest.Create? Is there something else I'm doing wrong? 还有别的我做错了吗?

I appreciate any kind of help and suggestions. 我感谢任何帮助和建议。

Since WebRequest.Create uses Dns.GetHostByName internally which is a blocking method (and sometimes really slow) your code can be blocked at that point. 由于WebRequest.Create 内部使用Dns.GetHostByName这是一种阻塞方法(有时非常慢),因此可以在此时阻止您的代码。

A simple workaround can be creating a task and awating it 一个简单的解决方法可以是创建任务并对其进行授权

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

I would suggest switching to HttpClient as the recommended client moving forward. 我建议切换到HttpClient作为推荐的客户端继续前进。 (Thanks for the reminder Erik) (感谢提醒Erik)

This will need some updates to fit your needs but it is a starting point for making the transition. 这需要一些更新以满足您的需求,但它是进行转换的起点。

            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();
                }
            }

you can convert any piece of code into async code by using 你可以使用任何一段代码转换成异步代码

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

but i think as long as your entry method is async then everything under that runs in async with reference to the code calling that method. 但我认为只要您的入口方法是异步的,那么下面的所有内容都会在异步中运行,并引用调用该方法的代码。

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

should therefore be running without blocking your UI cuz you are not expected to convert everthing to be async. 因此,应该在不阻止UI的情况下运行,因为您不希望将everthing转换为异步。

please also check when you are calling this "function" you are using async/await over there. 请同时检查您在调用此“功能”时是否正在使用async / await。 if you have resharper, that will generally tell you when you are missing async/await in such scenario, because without that you could be calling your method synchronously. 如果你有resharper,那通常会告诉你在这种情况下你何时缺少async / await,因为没有它你可以同步调用你的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM