Search code examples
c#backgroundworkerwebclientdownloadstring

BackgroundWorker with Webclient downloadstring


So basically I want to retrieve the content of a .txt file on the internet and write it into a a label. However though, while it does this Windows Forms freezes.

So I thought of putting it into a BackgroundWorker. There is also a progress bar which should be filled during the progress. My code looks like this:

private void RetrieveTxt(string currentversion)
    {
        worker.DoWork += new DoWorkEventHandler(worker_DoWork);
        worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    }

void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        WebClient wc = new WebClient();
        label1.Text = wc.DownloadString("http://example.org/version.txt");
    }

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        updateProgress.Value = e.ProgressPercentage;
    }

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        updateProgress.Visible = false;
    }

However though, it doesn't work; the label never gets updated and the progress bar stays empty.

Any help is appreciated, thank you! :)


Solution

  • If you're using C# 5.0 you can do the following:

    label1.Text = await client.DownloadStringTaskAsync("http://example.org/version.txt");
    

    It's just that easy.

    If you're not, then you can leverage the async support of WebClient; you don't need to use a BackgroundWorker:

    WebClient client = new WebClient();
    client.DownloadStringCompleted += (s, data) =>
    {
        label1.Invoke(new Action(() => label1.Text = data.Result));
    };
    client.DownloadStringAsync(new Uri("http://example.org/version.txt"));
    

    As for why your code doesn't work:

    1. You never actually started the worker. You never called worker.RunWorkerAsync();
    2. You're accessing a UI control from a background task, so it will just break when you try to access the label from the DoWork handler. You would need to set the result to be the string that the WebClient returns and then set the label in the completed handler.