【问题标题】:GUI hangs if i make requests and responses from HttpWebRequest and HttpWebResponse如果我从 HttpWebRequest 和 HttpWebResponse 发出请求和响应,GUI 会挂起
【发布时间】:2015-09-14 09:41:54
【问题描述】:

我有 ac#win forms 程序来检查 URL 是否存在。该程序工作正常,但是当我使用按钮单击开始进程时,gui 挂起,直到检查完成。我基本上是单击按钮并执行下面的代码。请帮助我了解如何实现后台工作程序或其他线程处理,以便我可以访问我的 GUI。

// 这是我单击的按钮,然后我的 GUI 挂起(无法访问),直到两个函数都执行。

 private void button2_Click(object sender, EventArgs e)   
            {
                performfetch();      
            }

    public void performfetch()
            {
                button2.Enabled = false;
                button1.Enabled = false;
                button2.Visible = false;
                button1.Visible = false;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = int.Parse(label2.Text) - 1;
                for (int i = 0; i < int.Parse(label2.Text); i++)
                {
                    string URL = dataGridView1[0, i].Value.ToString();
                    dataGridView1[1, i].Value = URLExists(URL);
                    progressBar1.Value = i;
                }
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {

                    if (dataGridView1[1, i].Value.ToString() == "Found")
                    {
                        // dataGridView1[1, i].Style.ForeColor = Color.Green;
                        dataGridView1[1, i].Style.ForeColor = Color.Green;
                    }
                    else
                    {
                        dataGridView1[1, i].Style.ForeColor = Color.Red;
                        // dataGridView1[2, i].Style.ForeColor = Color.Red;
                    }
                }
                label6.Text = "Checking Links Completed";
                button2.Enabled = true;
                button1.Enabled = true;
                button2.Visible = true;
                button1.Visible = true;
            }


     static public String URLExists(string url)
            {
                String result = "Not Found";
               try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = WebRequestMethods.Http.Head;
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        response.Close();
                        result = "Found";
                        return result;
                    }

                }
                catch
                {
                                 return result;
               }

                 return result;

            } 

【问题讨论】:

  • 你把代码放到BackgroundWorker中,然后处理结果。有什么具体问题吗?
  • 另一种方法是启动一个线程来更新 URL 状态(找到与否)。在这种情况下,您应该使用计时器来更新 UI,或者在应用程序最开始时启动线程并在其他初始化结束时显示状态(仅当初始化过程持续超过 n 秒时)。
  • 我不知道该怎么做。请您编辑我的脚本并让我知道如何实施,因为这对我很有帮助:) 感谢您的回复
  • 主线程上的任何网络操作都会阻塞。您需要生成一个新线程来检查您的 url,然后使用委托更新 ui,因为您也无法从单独的线程更新 ui 线程(主)。

标签: c# multithreading user-interface backgroundworker


【解决方案1】:

在计时器事件中进行 UI 更新的一些代码。

private enum Status { Pending, FoundUnprocessed, FoundProcessed, NotFoundNotProcessed, NotFoundProcessed }
private List<Status>   URLStatuses = new List<bool>() ;
private List<string>   URLs        = new List<string>() ;


private void StartUrlsThreads()
{
  for (int i = 0; i < int.Parse(label2.Text); i++)
  {
     URLs.Add(dataGridView1[0, i].Value.ToString());
     URLStatuses.Add(false) ; 
     Thread newThread = new Thread(new ThreadStart(URLExists));
     newThread.Start(URLs[i]) ;
  }
}

private void URLExists(object urlobj)
{
  try
  {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create((string)urlobj);
    request.Method = WebRequestMethods.Http.Head;
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    if (response.StatusCode == HttpStatusCode.OK)
    {
       response.Close();
       URLStatuses[URLs.IndexOf((string)urlobj)]=Status.FoundUnprocessed ;
    }
    else URLStatuses[URLs.IndexOf((string)urlobj)]=Status.NotFoundUnprocessed ;
  }       
  catch { URLStatuses[URLs.IndexOf((string)urlobj)]=Status.NotFoundUnprocessed ; }
}

private void timer1_Tick(object sender, EventArgs e)
{
  for (int i=0;i<URLs.Count;i++) 
  {
    if (URLStatuses[i]==Status.FoundUnprocessed) 
    {
   URLStatuses[i]==Status.FoundProcessed ;
       // update DataGridView && progressbar
    }
    if (URLStatuses[i]==Status.NotFoundUnprocessed) 
    {
   URLStatuses[i]==Status.NotFoundProcessed ;
       // update DataGridView && progressbar
    }
// stop timer if no more pending status
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-01
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2011-10-07
    相关资源
    最近更新 更多