Form Not Responding when any other operation performed in C#

前端 未结 5 1072
心在旅途
心在旅途 2020-12-09 12:52

I have a form (Developed in C# using VS2010) with a Progress Bar. It\'s kind of stopwatch form where I fill the progress bar in say 10secs.... As Time elapses, Progress bar

相关标签:
5条回答
  • 2020-12-09 13:02

    You're performing a long-running operation on the UI thread, which means that the UI "message loop" (responsible for handling events such as user input and updating the screen) doesn't get a chance to run.

    You should perform the long-running operation on a different thread (whether one you create yourself or a background thread) and either use BackgroundWorker to easily update your progress bar, or use Control.Invoke/BeginInvoke to marshall a delegate call back to the UI thread when you need to update the UI. (You mustn't update controls from the wrong thread.)

    If your only UI interaction is filling in a progress bar, I suggest using BackgroundWorker.

    If you're not really doing "real" work, just waiting for time to pass, you could use a System.Windows.Forms.Timer instead of all of this, however. That will "tick" on the UI thread, but won't block the UI thread between ticks. You should only use this if you don't have a lot of work to do though - if it really is just updating a progress bar, not (say) processing a file etc. Note that you shouldn't rely on the timer firing exactly "on time" - you should probably set the position of the progress bar based on the observed time, rather than the observed number of ticks.

    0 讨论(0)
  • 2020-12-09 13:06

    You are blocking the UI thread, which means it isn't processing events such as "paint". To do this properly, you should be using something like BackgroundWorker, and just updating the UI from the progress event.

    using System;
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Threading;
    
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MyForm());
        }
    }
    
    class MyForm : Form
    {
        Button btn;
        BackgroundWorker worker;
        ProgressBar bar;
        public MyForm()
        {
            Controls.Add(btn = new Button { Text = "Click me" });
            btn.Click += new EventHandler(btn_Click);
    
            Controls.Add(bar = new ProgressBar { Dock = DockStyle.Bottom, Visible = false, Minimum = 0, Maximum = 100 });
    
            worker = new BackgroundWorker { WorkerReportsProgress = true };
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        }
    
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            bar.Visible = false;
            if (e.Error != null)
            {
                Text = e.Error.Message;
            }
            else if (e.Cancelled)
            {
                Text = "cancelled";
            }
            else
            {
                Text = e.Result == null ? "complete" : e.Result.ToString();
            }
            btn.Enabled = true;
        }
    
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int count = 0; count < 100; count++)
            {
                worker.ReportProgress(count);
                Thread.Sleep(50);
            }
        }
    
        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            bar.Value = e.ProgressPercentage;
        }
    
        void btn_Click(object sender, EventArgs e)
        {
            bar.Value = 0;
            bar.Visible = true;
            btn.Enabled = false;
            worker.RunWorkerAsync();
        }
    }
    
    0 讨论(0)
  • 2020-12-09 13:21

    Answer suggested by Marc will help. Lon running operations can make your application crash or not responsive. I have a blog post related to the usage of the background worker class.

    http://midnightprogrammer.net/post/Using-Background-Worker-in-C.aspx

    0 讨论(0)
  • 2020-12-09 13:24

    You are blocking the Main UI thread. You can use a background worker to do this. You can find more details in MSDN

    0 讨论(0)
  • 2020-12-09 13:24

    If you want to run your code you should put this code in a function and call this function with one thread.

     public static void fun1()
            {
                for (int i = 0; i <= 10; i++)
                {
                    Console.Write("This is function1");
                    Console.Write("\n");
    
                }
    
            }
      Thread firstthread = new Thread(new ThreadStart(fun1));
    
      firstthread.Start();
      firstthread.suspend();//whenever you want your current control to stop.
    

    b'caz Thread.sleep(100) will stop the whole context not that particular you want..

    0 讨论(0)
提交回复
热议问题