Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

My Form is not responding

Posted on 2009-05-17
14
Medium Priority
?
508 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
[X]
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
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

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 200 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 1400 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 86

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 200 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 200 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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …

650 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