在等待WebClient时继续使用UI

时间:2013-04-29 20:16:55

标签: c# multithreading webclient

我正在尝试获取进度条以显示程序正在加载(使用ProgressStyle.Marquee),而WebClient对象从站点读取。问题是,在单击开始呼叫的按钮时,整个UI会冻结。我已经尝试将它放在BackgroundWorker doWork中,但这导致它永远不会得到任何数据。我也尝试了代理和各种线程选项,但似乎都有同样的问题。

我是C#的新手,并且大部分都在尝试我在网上找到的结果,但似乎没有解决我的问题。

我有什么:

private void getInfoButton_Click(object sender, EventArgs e)
{
    progressBar1.Style = ProgressBarStyle.Marquee;
    getInfoButton.Enabled = false;
    StreamReader reader = new StreamReader(client.OpenRead("URI here"));
    while ((line = reader.ReadLine()) != null) {
        // Do stuff
    }
    progressBar1.Style = ProgressBarStyle.Continuous;
    getInfoButton.Enabled = true;
}

我尝试使用BackgroundWorker

private void getInfoButton_Click(object sender, EventArgs e)
{
    progressBar1.Style = ProgressBarStyle.Marquee;
    getInfoButton.Enabled = false;
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWord += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerAsync("URI here");
    while (bw.IsBusy)
        ;
    progressBar1.Style = ProgressBarStyle.Continuous;
    getInfoButton.Enabled = true;
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    WebClient client = new WebClient();
    StreamReader reader = new StreamReader(e.Argument);
    while ((line = reader.ReadLine()) != null) {
        // Do stuff
    }        
}

1 个答案:

答案 0 :(得分:0)

在查看我的BackgroundWorker尝试之后,我意识到它正在打败异步性,getInfoButton_Click方法将停止(有效冻结UI)直到完成。使用BackgroundWorker,我设法让它工作:

private void getInfoButton_Click(object sender, EventArgs e)
{
    progressBar1.Style = ProgressBarStyle.Marquee;
    getInfoButton.Enabled = false;
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
    bw.RunWorkerAsync("URI Here");
}

void bw_DoWork(object sender, DoWorkEventArgs e)
{
        WebClient client = new WebClient();
        StreamReader reader = new StreamReader(client.OpenRead(e.Argument));
        e.Result = reader;
}

void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    StreamReader reader = (StreamReader)e.Result;
    while ((line = reader.ReadLine()) != null) {
        // Do stuff
    }
    progressBar1.Style = ProgressBarStyle.Continuous;
    getInfoButton.Enabled = true;
}