Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# Async
Hello,
 
Why my form does not respond on user actions with following code?
 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Net;
 
namespace SharpFive
{    
    public partial class Form1 : Form
    {
        public string m_text
        {
            get
            {
                return textBox1.Text;
            }
            set
            {
                textBox1.BeginInvoke(new Action(() => textBox1.Text = m_text + Environment.NewLine + value));
            }
        }
        
        private static readonly List<string> urlArray = new List<string>
        {
                                                                 "http://www.google.com",
                                                                 "http://www.bing.com",
                                                                 "http://www.oreilly.com",
                                                                 "http://www.simple-talk.com",
                                                                 "http://www.microsoft.com",
                                                                 "http://www.facebook.com",
                                                                 "http://www.twitter.com",
                                                                 "http://www.reddit.com",
                                                                 "http://www.baidu.com",
                                                                 "http://www.bbc.co.uk"
        };        
        public Form1()
        {            
            InitializeComponent();           
        }       
 
        private void button1_Click(object sender, EventArgs e)
        {
            goingOn on = new goingOn(this);
            foreach (string domain in urlArray)
            {
                on.Docompute(domain);
            }
        }
    }
    class goingOn
    {
        private readonly Form1 form;
        public goingOn(Form1 form)
        {
            this.form = form;
        }
        private async Task<int> fire(string url)
        {
            WebClient webClient = new WebClient();
            string page = await webClient.DownloadStringTaskAsync(url);
            Thread.Sleep(1000);
            return page.Length;
        }
        public async void Docompute(string urls)
        {
            int size = 0;                      
            size = await fire(urls);            
            //form.m_text = size.ToString();
        } 
    }
}
Posted 17-Jan-13 8:03am
MeSaNei354
Comments
Sergey Alexandrovich Kryukov at 17-Jan-13 13:33pm
   
What makes you believe it's locked? It cannot get locked unless you lock it intentionally? Do you do any blocking call in UI thread?
—SA
MeSaNei at 17-Jan-13 14:27pm
   
The UI becomes unresponsive. The code above is complete code i run.
Sergey Alexandrovich Kryukov at 17-Jan-13 14:40pm
   
I see...
—SA
MeSaNei at 18-Jan-13 8:30am
   
Another solution to this situation is to use Task.Run.
Task.Run uses a thread from the ThreadPool to execute the delegate you give it.
So:
Task t = Task.Run(() => {
foreach (string domain in urlArray)
{
on.Docompute(domain);
}
});

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Here is what I can see: you are using Thread.Sleep. I don't have v.4.5 to test it, but let's see: it's explicitly documented, that the invocation of async methods does not create a new thread; using them does not require multithreading: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads[^].
 
It looks like you don't create any threads either. Now, let's combine these facts with the principle "there is no such thing as miracle". What is the thread where you call Thread.Sleep then? This is you UI thread. No wonder it becomes unresponsive for a while. If you repeat it on regular basis, it will be permanently unresponsive.
 
Did you follow my logic? So, it looks like if you want to use the pattern based on Sleep (which is itself perfectly fine), you can practically do it only using "real" threading paradigm.
 
Generally, I find Microsoft claim "The async-based approach to asynchronous programming is preferable to existing approaches in almost every case" (on the page I referenced above) highly exaggerated. This is not innovative in its basic aspects, just the opposite, it looks like getting back to old times when cooperative multithreading was more extensively used. It has its value, of course, for number of models, but it should be used with care, the care is some different ways than with threads.
 
—SA
  Permalink  
Comments
Espen Harlinn at 17-Jan-13 16:33pm
   
5'ed!
>> is not innovative in its basic aspects
Once there was a 16-bit OS called Windows 3.x - it required that we did asynch socket programming ... and most of us were quite happy to get away from that ...
Sergey Alexandrovich Kryukov at 17-Jan-13 16:40pm
   
Thank you, Espen.
Exactly. And, but the way, that's why by that time I have my own multithreaded system written from scratch, at the CPU level. At that time, even Linux did not have threads, only processes...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web03 | 2.8.150302.1 | Last Updated 17 Jan 2013
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100