Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C#
  4. Working with the UI while multithreading

Working with the UI while multithreading

Scheduled Pinned Locked Moved C#
questiondesigntutorial
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Islorvat
    wrote on last edited by
    #1

    Hello! I am trying to understand more about threading but i can't find how to 'free' the UI from the threads working in the background. How can i use my form's controls or move/resize the window while a progressbar is updated from a loop in another thread? Here is the code:

        delegate void \_delegate(); 
    
        private void button1\_Click(object sender, EventArgs e)
        {
            Thread t1 = new Thread(new ThreadStart(ProgressUpdate));
            t1.Start();
        }
    
        void ProgressUpdate()
        {
            if (progressBar1.InvokeRequired)
            {
                progressBar1.Invoke(new \_delegate(Progress));    
            }
    
            else
            {
                for (int i = 1; i <= 100; i++)
                {
                    progressBar1.Value = (i \* 100) / 100;
                    Thread.Sleep(50);
                }
            }
        }
    
        void Progress()
        {
            for (int i = 1; i <= 100; i++)
            {
                progressBar1.Value = i;
                Thread.Sleep(50);
            }
        }
    
    L T 2 Replies Last reply
    0
    • I Islorvat

      Hello! I am trying to understand more about threading but i can't find how to 'free' the UI from the threads working in the background. How can i use my form's controls or move/resize the window while a progressbar is updated from a loop in another thread? Here is the code:

          delegate void \_delegate(); 
      
          private void button1\_Click(object sender, EventArgs e)
          {
              Thread t1 = new Thread(new ThreadStart(ProgressUpdate));
              t1.Start();
          }
      
          void ProgressUpdate()
          {
              if (progressBar1.InvokeRequired)
              {
                  progressBar1.Invoke(new \_delegate(Progress));    
              }
      
              else
              {
                  for (int i = 1; i <= 100; i++)
                  {
                      progressBar1.Value = (i \* 100) / 100;
                      Thread.Sleep(50);
                  }
              }
          }
      
          void Progress()
          {
              for (int i = 1; i <= 100; i++)
              {
                  progressBar1.Value = i;
                  Thread.Sleep(50);
              }
          }
      
      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      you got it wrong. Having Control.InvokeRequired and Control.Invoke the way you did is just fine, however they cause the else block in ProgressUpdate to execute on the GUI thread (that was the intention all along), so that else block should NOT contain lengthy operations nor calls to Thread.Sleep You should perform all timing by: - using timers; - OR using whatever you like on YOUR threads; - but not by using Thread.Sleep on the GUI thread. So a better approach would be to have the thread execute some method, say Progress, which contains any delay you like, and calls ProgressUpdate (the new one without any Sleep) to update the GUI. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


      Getting an article published on CodeProject now is hard and not sufficiently rewarded.


      1 Reply Last reply
      0
      • I Islorvat

        Hello! I am trying to understand more about threading but i can't find how to 'free' the UI from the threads working in the background. How can i use my form's controls or move/resize the window while a progressbar is updated from a loop in another thread? Here is the code:

            delegate void \_delegate(); 
        
            private void button1\_Click(object sender, EventArgs e)
            {
                Thread t1 = new Thread(new ThreadStart(ProgressUpdate));
                t1.Start();
            }
        
            void ProgressUpdate()
            {
                if (progressBar1.InvokeRequired)
                {
                    progressBar1.Invoke(new \_delegate(Progress));    
                }
        
                else
                {
                    for (int i = 1; i <= 100; i++)
                    {
                        progressBar1.Value = (i \* 100) / 100;
                        Thread.Sleep(50);
                    }
                }
            }
        
            void Progress()
            {
                for (int i = 1; i <= 100; i++)
                {
                    progressBar1.Value = i;
                    Thread.Sleep(50);
                }
            }
        
        T Offline
        T Offline
        Tim Weckx
        wrote on last edited by
        #3

        The easiest way to multithread in a WinForms application is by using a BackgroundWorker. With it, you don't need to worry about InvokeRequired and Control.Invoke, it takes care of this for you. You can get more details on the MSDN website (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx[^]) , but below is a simple example.

        private void button1_Click(object sender, EventArgs e)
        {
        // Create a new backgroundworker that supports progressreporting and cancellation.
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        worker.WorkerSupportsCancellation = true;

                // Hook up the events that will do the actual work
                worker.DoWork += new DoWorkEventHandler(worker\_DoWork);
                worker.ProgressChanged += new ProgressChangedEventHandler(worker\_ProgressChanged);
                worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker\_RunWorkerCompleted);
        
                // Start the background worker
                worker.RunWorkerAsync();
            }
        
            void worker\_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                // When an exception happens in the do\_work eventhandler,
                // the RunWorkerCompleted is called with the exception passed on the argument.
                // Always check for this
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                }
                else if (e.Cancelled)
                {
                    // show the user that the background worker was cancelled
                }
                else
                {
                    // show the user that the worker completed succesfully
                }
            }
        
            void worker\_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                progressBar1.Value = e.ProgressPercentage;
            }
        
            void worker\_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = (BackgroundWorker)sender;
        
                // perform the time consuming task
                for (int i = 1; i <= 100; i++)
                {
                    if (!worker.CancellationPending) // this is only needed if your task can be cancel
        
        I 1 Reply Last reply
        0
        • T Tim Weckx

          The easiest way to multithread in a WinForms application is by using a BackgroundWorker. With it, you don't need to worry about InvokeRequired and Control.Invoke, it takes care of this for you. You can get more details on the MSDN website (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx[^]) , but below is a simple example.

          private void button1_Click(object sender, EventArgs e)
          {
          // Create a new backgroundworker that supports progressreporting and cancellation.
          BackgroundWorker worker = new BackgroundWorker();
          worker.WorkerReportsProgress = true;
          worker.WorkerSupportsCancellation = true;

                  // Hook up the events that will do the actual work
                  worker.DoWork += new DoWorkEventHandler(worker\_DoWork);
                  worker.ProgressChanged += new ProgressChangedEventHandler(worker\_ProgressChanged);
                  worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker\_RunWorkerCompleted);
          
                  // Start the background worker
                  worker.RunWorkerAsync();
              }
          
              void worker\_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
                  // When an exception happens in the do\_work eventhandler,
                  // the RunWorkerCompleted is called with the exception passed on the argument.
                  // Always check for this
                  if (e.Error != null)
                  {
                      MessageBox.Show(e.Error.Message);
                  }
                  else if (e.Cancelled)
                  {
                      // show the user that the background worker was cancelled
                  }
                  else
                  {
                      // show the user that the worker completed succesfully
                  }
              }
          
              void worker\_ProgressChanged(object sender, ProgressChangedEventArgs e)
              {
                  progressBar1.Value = e.ProgressPercentage;
              }
          
              void worker\_DoWork(object sender, DoWorkEventArgs e)
              {
                  BackgroundWorker worker = (BackgroundWorker)sender;
          
                  // perform the time consuming task
                  for (int i = 1; i <= 100; i++)
                  {
                      if (!worker.CancellationPending) // this is only needed if your task can be cancel
          
          I Offline
          I Offline
          Islorvat
          wrote on last edited by
          #4

          Thanks a lot!

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups