While循环锁定UI线程

时间:2018-06-20 06:48:01

标签: c# multithreading winforms webclient

我的WinForms应用程序中有一个带有以下Click事件的按钮:

    private void Button_Click(object sender, EventArgs e)
    {
        treasureFound = false;
        refreshNumber = 0;

        Label_StartDateTime.Text = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");
        while (!treasureFound)
        {
            Label_StatusData.Text = "Refreshed " + refreshNumber + " times.";
            refreshNumber++;
            using (WebClient client = new WebClient())
            {
                string htmlCode = client.DownloadString(webUrl);

                if (htmlCode.Contains("Treasure"))
                {
                    treasureFound = true;
                    Label_StatusData.Text = "Found.";
                    // etc etc
                }
            }
        }
    }

单击按钮后,UI线程将锁定(不响应,标签不会更新),直到while循环结束。

我该怎么做才能使UI保持响应状态?任何时候都只能有一个WebClient实例。

1 个答案:

答案 0 :(得分:1)

您应该在单独的线程中执行耗时的任务,因此它不会阻塞主线程(也就是您的UI线程)。一种方法是使用BackgroundWorker。

public Form1()
{
    InitializeComponent();

    backgroundWorker1.DoWork += backgroundWorker1_DoWork;
    backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
    backgroundWorker1.WorkerReportsProgress = true;
}

private void button1_Click(object sender, EventArgs e)
{
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);
    }
}

private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

来自:How to use a BackgroundWorker?