Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

My Form is not responding

Posted on 2009-05-17
14
487 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
How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

 

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
 

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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
defining NULL or 0 10 44
"Emulate" TAB key when press Enter Key 3 47
Tracing a live website down to the files which support it 2 25
C# Linq Select From List 3 17
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:…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

828 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