Solved

My Form is not responding

Posted on 2009-05-17
14
460 Views
Last Modified: 2013-12-17
Hi,
When I run my code, and click a button, the msgs are dispalyed in the rich textbox.
When I tried to move the scroll bar on the richtextbox while the process was still running, the whole form became "not responding."
What should I do to use my scroll bar to see all the displays while the process is still running?

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Update();
            this.richTextBox1.Clear();          
           
            for (int i = 0; i < 3; i++)
           {
                AddHi(i);
                Thread.Sleep(10000);
                AddBye(i);
            }
               
           
            this.button1.Enabled = true;
        }    
        public delegate void GreetingDelegate(string str);
        public void AddGreeting(string str)
        {
            if (this.richTextBox1.InvokeRequired)
            {
                this.richTextBox1.Invoke(new GreetingDelegate(AddGreeting), str);
                return;
            }
            else
            {
                this.richTextBox1.AppendText(str);
                this.richTextBox1.Refresh();
            }
        }        
        public void AddHi(int i)
        {
            try
            {
                AddGreeting("Hi " + i.ToString() + "\n");

            }
            catch (Exception e)
            {
                e.Message.ToString();
            }
        }

        public void AddBye(int i)
        {
            try
            {
                AddGreeting("Bye " + i.ToString() + "\n");

            }
            catch (Exception e)
            {
                e.Message.ToString();
            }
        }        
    }
}
0
Comment
Question by:IzzyTwinkly
  • 6
  • 2
  • 2
  • +4
14 Comments
 
LVL 5

Expert Comment

by:Aanvik
ID: 24408878
0
 

Author Comment

by:IzzyTwinkly
ID: 24409007
My form still gets 'not responding' with Application.DoEvent().  Is put that in the for loop from my code.
0
 
LVL 13

Expert Comment

by:SameerJagdale
ID: 24409027
try removing
Thread.Sleep(10000);

from your code.
0
 

Author Comment

by:IzzyTwinkly
ID: 24409034
Thread.Sleep(10000) should be there.  that simulates a method that takes some time to process.  
0
 
LVL 11

Assisted Solution

by:saragani
saragani earned 50 total points
ID: 24409102
Let me explain you a little about threads.

The GUI runs on the main thread of the application. Once you do an infinite loop or sleep (in your cause for 10 seconds), the main thread become locked and the GUI doesn't redraw itself.

This is why your form is not responding.

In my opinion Any action that takes 500 Milliseconds  should be performed on another thread.


Your form should start a new thread that will do the long process job, while in the meanwhile the parts in the form that need to be disabled get disabled.

When the thread finished doing what it supposed to do then it re-enables what it needs in the form and do whatever action in needs to do in the form, all of that while considering thread safety and preventing cross-thread access to the GUI
(You will need to use delegates to do this.Invoke when this.InvokeRequired is true)
0
 
LVL 11

Accepted Solution

by:
anyoneis earned 350 total points
ID: 24409196
saragani has it. But since I had coded this change for you, here it is:
 
David

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Threading;
 

namespace RichTextDelay

{

    public partial class Form1 : Form

    {

        Thread backgroundThread = null;
 

        public Form1()

        {

            InitializeComponent();

        }
 

        private void button1_Click(object sender, EventArgs e)

        {

            this.button1.Enabled = false;

            this.richTextBox1.Update();

            this.richTextBox1.Clear();

            backgroundThread = new Thread(delegate() { DoStuff(); });

            backgroundThread.Start();

        }

        private void DoStuff()

        {

            for (int i = 0; i < 3; i++)

            {

                AddHi(i);

                Thread.Sleep(10000);

                AddBye(i);

            }

            this.Invoke((MethodInvoker) delegate { this.button1.Enabled = true; });

        }

        

        public delegate void GreetingDelegate(string str);

        public void AddGreeting(string str)

        {

            if (this.richTextBox1.InvokeRequired)

            {

                this.richTextBox1.Invoke(new GreetingDelegate(AddGreeting), str);

                return;

            }

            else

            {

                this.richTextBox1.AppendText(str);

                this.richTextBox1.Refresh();

            }

        }        

        public void AddHi(int i)

        {

            try

            {

                AddGreeting("Hi " + i.ToString() + "\n");
 

            }

            catch (Exception e)

            {

                e.Message.ToString();

            }

        }
 

        public void AddBye(int i)

        {

            try

            {

                AddGreeting("Bye " + i.ToString() + "\n");
 

            }

            catch (Exception e)

            {

                e.Message.ToString();

            }

        }
 

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)

        {

            if (backgroundThread != null)

            {

                backgroundThread.Abort();

                backgroundThread = null;

            }

        }        

    }

}

Open in new window

0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 50 total points
ID: 24409236
If you want to "simulate" long "work" then try something like this:

    Delay(10); // delay for ten seconds

The method:
        private void Delay(int DelayInSeconds)

        {

            TimeSpan ts;

            DateTime targetTime = DateTime.Now.AddSeconds(DelayInSeconds);

            do

            {

                ts = targetTime.Subtract(DateTime.Now);

                Application.DoEvents(); // keep app responsive

                System.Threading.Thread.Sleep(50); // reduce CPU usage

            }

            while (ts.TotalSeconds > 0);

        }

Open in new window

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:IzzyTwinkly
ID: 24409257
I see your point saragani.  I guess you mean I need to use the method(in this case, Thread.Sleep(10000)) with a new thread between AddHi(i) and AddBye(i).  I guess I also need to make AddBye(i) wait until Thread.Sleep(10000) is all done.
Could you show me some example or code?  I checked msdn, but still confusing how to apply cross-thread solution in my case.
0
 

Author Comment

by:IzzyTwinkly
ID: 24409264
oh  I have some codes now.  never mind my previous comment.  Thanks!
0
 
LVL 16

Assisted Solution

by:CuteBug
CuteBug earned 50 total points
ID: 24409266
You can modify your code like this
public partial class Form1 : Form

{

    bool wait = true;
 

    public Form1()

    {

        InitializeComponent();

    }
 

    private void button1_Click(object sender, EventArgs e)

    {

        this.button1.Enabled = false;
 

        this.richTextBox1.Update();

        this.richTextBox1.Clear();
 

        for (int i = 0; i < 3; i++)

        {

            AddHi(i);
 

            Thread waitThread = new Thread(new ThreadStart(WaitMethod));

            waitThread.Start();

            while (wait)

            {

                Application.DoEvents();

            }
 

            AddBye(i);

        }

        

        this.button1.Enabled = true;

    }
 

    public void WaitMethod()

    {

        Thread.Sleep(10000);

        wait = false;

    }
 

    public delegate void GreetingDelegate(string str);

    

    public void AddGreeting(string str)

    {

        if (this.richTextBox1.InvokeRequired)

        {

            this.richTextBox1.Invoke(new GreetingDelegate(AddGreeting), str);

            return;

        }

        else

        {

            this.richTextBox1.AppendText(str);

            this.richTextBox1.Refresh();

        }

    }
 

    public void AddHi(int i)

    {

        try

        {

            AddGreeting("Hi " + i.ToString() + "\n");
 

        }

        catch (Exception e)

        {

            e.Message.ToString();

        }

    }
 

    public void AddBye(int i)

    {

        try

        {

            AddGreeting("Bye " + i.ToString() + "\n");
 

        }

        catch (Exception e)

        {

            e.Message.ToString();

        }

    }

}

Open in new window

0
 

Author Comment

by:IzzyTwinkly
ID: 24409559
Wow..it's really cool. Thanks!

I have a qucik question from your code, anyoneis.
Could you explain 'this.Invoke((MethodInvoker) delegate { this.button1.Enabled = true; });' little bit?  I guess that you are make the button enable, but I want to know more detailed steps with Invoke, MethodInvoker, etc...
0
 
LVL 11

Expert Comment

by:saragani
ID: 24409655
He is using something called Anonymous Methods. It is a cool thing that Vb.Net doesn't support.

This is a good example of updating the GUI from another thread:
http://www.codeproject.com/KB/cs/ModelViewPresenterWithDI.aspx

This is where I first saw the cool usage of anonymous methods (before that I had to write my own delegates, and lots of them, for doing this.invoke).

Just search for UpdateUI in that article.
0
 
LVL 11

Expert Comment

by:anyoneis
ID: 24415106
It is just a shorthand for the same thing you did with GreetingDelegate - it reduces all of the delegate declarations and little event functions that you have to write.
I like this article: http://www.yoda.arachsys.com/csharp/csharp2/delegates.html#anonymous.methods
where he gives this example:
using System;
delegate void SomeAction();
class Test
{
     static void Main(string[] args)
     {
          SomeAction instance = delegate { Console.WriteLine(args[0]); }; instance();
     }
}  
The reason the above works is becuase the compiler knows what kind of delegate it needs (SomeAction.). In my cvase, it did not, so I had to tell it with a cast. I hjave seen others use "Action" as the delegate type in this situation.
            this.Invoke((MethodInvoker) delegate { this.button1.Enabled = true; });.
 David
0
 

Author Comment

by:IzzyTwinkly
ID: 24415144
Thank you so much.  
I might need to open another question about cross threaded operation. =)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now