0

im trying to download a string on a separate non ui thread and when it is done downloading update the ui, but i want to do it without the ui freezing, so i tried to make a thread but that didnt work, and then i tried to make a thread in that thread but that also didnt work how do i call the downloadstring function without freezing the ui?

public partial class Form1 : Form
{
    private delegate void displayDownloadDelegate(string content);
    public Thread downloader, web;
    public Form1()
    {
        InitializeComponent();
    }
    // Go (Download string from URL) button
    private void button1_Click(object sender, EventArgs e)
    {
        textBox1.Enabled = false;

        string url = textBox1.Text;
        Thread web = new Thread(() => webDownload(url));
        web.Start();

    }
    // Go (sorting) button
    private void button2_Click(object sender, EventArgs e)
    {

    }
    public void webDownload(string address)
    {
        Thread next = new Thread(() => downloading(address));
        next.Start();
        //  next.Join();

    }
    public void downloading(string address){

        using (WebClient client = new WebClient())
        {
           string content = client.DownloadString(address);
           textBox2.BeginInvoke(new displayDownloadDelegate(displayDownload), content);

        }

   }
    private void displayDownload(string content)
    {
        textBox2.Text = content;
    }
  • 6
    "but that didnt work" doesn't tell us anything about what you observed. I'd suggest using the async methods personally, with async/await (ideally using HttpClient too) – Jon Skeet Jul 25 '15 at 22:08
  • There is no exception handling in this example, and if you're using a thread like you do here, any exceptions that occur in your threads will just be swallowed by the runtime. MIght be worth look into the BackgroundWorker component for this kind of job (or just do what @JonSkeet suggested and try using async/await against the async methods) – havardhu Jul 25 '15 at 22:18
  • by that didnt work i meant it continued to freeze the ui, do you know how you could do it without freezing the ui but still using webclient and not using the async methods? – user5156226 Jul 25 '15 at 22:19
  • Why "and not using the async methods" ? You are disqualifying the most sensible answer. – H H Jul 25 '15 at 22:25
  • With `HttpClient`, you can replace all your code with a single line `textBox2.Text = await httpClient.GetStringAsync(textBox1.Text)` – EZI Jul 25 '15 at 22:30
  • I'm not disqualifying the most sensible answer if the question explicitly states to use the SYNCHRONOUS call, and I was told it could be done so I'm trying to figure out how. – user5156226 Jul 25 '15 at 22:34
  • This should not block. Is that really all that you are doing? So are blocking somewhere else. Pause the debugger during the freeze. What's on the stack? – usr Jul 25 '15 at 22:34
  • http://stackoverflow.com/questions/9727928/webclient-wait-until-file-has-downloaded – CharithJ Jul 25 '15 at 22:41
  • hmm in the provided code there are two worker threads and only one is actually doing something. Why did not you call downloading() from webDownload() directly? – alexm Jul 25 '15 at 23:24

1 Answers1

1

Though you could simply use async-await with the asynchronous WebClient.DownloadStringTaskAsync method, if you really must use the synchronous WebClient.DownloadString method (for some reason) by executing it on a separate non-ui thread, you can still do that pretty simply with Task.Run() and async-await:

private async void button1_Click(object sender, EventArgs e)
{
    textBox1.Enabled = false;
    string url = textBox1.Text;

    using (WebClient client = new WebClient())
    {
        textBox2.Text = await Task.Run(() => client.DownloadString(url));
    }
}
sstan
  • 35,425
  • 6
  • 48
  • 66