-1

This is the code, i want my form keep be alive while downloading code from internet and when its finish i want to update html container. When i do this form freeze. I am new to threading and tasking and i need little help. Thanks!

 private void buttonGetHTML_Click(object sender, EventArgs e)
    {
        Task.Run(() => Download(textBoxUrl.Text)).ContinueWith((Download) => htmlContent.Text = Download.Result);
    }

    private string Download(string url)
    {
        using (WebClient client = new WebClient())
        {
            string context = client.DownloadString(url);
            return context;
        }
    }
  • `ContinueWith` is old style. Async/await is much easier to read, write and understand. It's just a wrapper, why not use it. – Nikhil Vartak Jun 05 '16 at 13:41

2 Answers2

4

Use this:

private async void buttonGetHTML_Click(object sender, EventArgs e)
{
    using (WebClient client = new WebClient())
    {
        string context = await client.DownloadStringAsync(textBoxUrl.Text);
        htmlContent.Text = content
    }
}

Most people try to solve this with Control.Invoke or something (see link in comment) but in this case there is a better option. Using the Async methods of the WebClient class. See https://msdn.microsoft.com/en-us/library/system.net.webclient.downloadstringasync(v=vs.110).aspx

Always look for Async methods first, before starting your own thread instead.

If you cannot use async await try this:

private void buttonGetHTML_Click(object sender, EventArgs e)
{
    var url = textBoxUrl.Text;
    Task.Run(() => Download(url)).ContinueWith((Download) => { htmlContent.Text = Download.Result; },  TaskScheduler.FromCurrentSynchronizationContext());
}

private string Download(string url)
{
    using (WebClient client = new WebClient())
    {
        string context = client.DownloadString(url);
        return context;
    }
}

So the call that accesses the UI is out of the Task and the continuation that accesses the UI will run on the UI thread.

Peter Bons
  • 26,826
  • 4
  • 50
  • 74
2

The reason is calling textBoxUrl.Text from non-UI thread. Try to retrieve the text first, then call Task.Run:

private void buttonGetHTML_Click(object sender, EventArgs e)
{
    var url = textBoxUrl.Text;
    Task.Run(() => Download(url)).ContinueWith((Download) => htmlContent.Text = Download.Result);
}
stop-cran
  • 4,229
  • 2
  • 30
  • 47