简体   繁体   English

使用HttpWebRequest时如何防止UI冻结?

[英]How can I prevent UI freezing while using HttpWebRequest?

I have a progressBar on my form and a button. 我的表单上有一个progressBar和一个按钮。 When user clicks this button, the progressBar should be styled as "marquee" and the program begins to check is an URL is valid or not.. OK. 当用户单击此按钮时,进度条应设置为“字幕”样式,程序开始检查URL是否有效。

But when I click the button, the UI freezes until the HttpStatusCode returns true or false... 但是,当我单击按钮时,UI冻结,直到HttpStatusCode返回true或false。

Here is the check code: 这是检查代码:

private bool RemoteFileExists(string url)
{
   try
   {
      HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
      request.Method = "HEAD";
      HttpWebResponse response = request.GetResponse() as HttpWebResponse;
      return (response.StatusCode == HttpStatusCode.OK);
   }
   catch
   {
      return false;
   }
}

And here is the button click code: 这是按钮点击代码:

private async void button1_Click(object sender, EventArgs e)
{
   this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
   var result = RemoteFileExists("http://www.google.com/");
   if (Completed)
   {
      //ok
   }
   else
   {
      //not ok
   }
}

The UI freezes because you are executing the RemoteFileExists method on the UI thread and receiving a response from a HttpWebRequest takes some time. UI冻结是因为您正在UI线程上执行RemoteFileExists方法,并且从HttpWebRequest接收响应需要一些时间。
To solve this you have to execute RemoteFileExists in a different thread than the UI thread. 为了解决这个问题,您必须在与UI线程不同的线程中执行RemoteFileExists
As your button1_Click method is already declared async the easiest way would be to declare RemoteFileExists as async too. 由于您的button1_Click方法已被声明为async所以最简单的方法就是也将RemoteFileExists声明为async
Then you can use the HttpWebRequest.GetResponseAsync method to asynchronously receive the response object. 然后,您可以使用HttpWebRequest.GetResponseAsync方法异步接收响应对象。

private async Task<bool> RemoteFileExists(string url)
{
   try
   {
      HttpWebRequest request = WebRequest.CreateHttp(url);
      request.Method = "HEAD";

      using(var response = (HttpWebResponse) await request.GetResponseAsync())
      {
          return (response.StatusCode == HttpStatusCode.OK);
      }
   }
   catch
   {
      return false;
   }
}

Also when dealing with IDisposable s you should take care of releasing all used resources by using the using statement or calling Dispose() . 同样,在处理IDisposable时,应注意通过使用using语句或调用Dispose()释放所有已使用的资源。
If you are using .NET Framework 4+ you can also use WebRequest.CreateHttp(string) to create your HttpWebRequest . 如果使用的是.NET Framework 4+,则还可以使用WebRequest.CreateHttp(string)创建HttpWebRequest

Putting it simple just use this: 简而言之,只需使用以下命令:

private void button1_Click(object sender, EventArgs e)
{
      this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Marquee;
      Thread thread = new Thread(() => RemoteFileExists("http://www.google.com/"));
      thread.IsBackground = true;
      thread.SetApartmentState(ApartmentState.STA);
      thread.Start();


}

And do the check inside RemoteFileExists . 并在RemoteFileExists .内部进行检查RemoteFileExists .

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

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