Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# VB.NET
I'm new in C # and I am developing a windows application in which I have a method that should be executed asynchronously, some tasks that this method has is to update some controls in the form. For this I am using a thread with an Invoke method to update the control that belongs to the form. This form has a button that starts this thread and one that should stop it. The problem is that because the use of the Invoke method the main thread, which is the form, is blocked until the other thread to finish, so I can not click on the button that stops the thread.
 
Below is a program that I created to try this. It has a class that adds the numbers from 1 to 100 in a listbox.
 
Main program.
 
private Thread thrAdicionarItens;
        private clcInvoke clcInvokeObject;
 
        private void btnExibir_Click(object sender, EventArgs e) {
            clcInvokeObject = new clcInvoke(lstItens);
            thrAdicionarItens = new Thread(new ThreadStart(clcInvokeObject.AdicionarItens));
            thrAdicionarItens.Start();
        }//End btnExibir_Click()

        private void btnParar_Click(object sender, EventArgs e) {
            try {
                thrAdicionarItens.Abort();
            }
            catch (Exception) {
            }
        }//End btnParar_Click()
 
Class code
 

 class clcInvoke
    {
        private ListBox lstItens;
 
        private delegate void dlgAdicionarItens();
 
        public clcInvoke(ListBox lstItens) {
            this.lstItens = lstItens;
        }//End clcInvoke()

        public void AdicionarItens() {
            try {
                if (lstItens.InvokeRequired == true)
                    lstItens.BeginInvoke(new dlgAdicionarItens(AdicionarItens));
                else
                    for (byte contador = 1; contador <= 100; contador++) {
                        lstItens.Items.Add(contador.ToString());
                        lstItens.Update();
                        Thread.Sleep(100);
                    }
            }
            catch (Exception) {
            }
        }//End AdicionarItens()

    }//End class clcInvoke
 

How do I a thread to upgrade, dynamically, a control on a form without making the form to be locked until the completion of another thread?
 
[Edit - Unchecked the "Treat my content as plain text, not as HTML" checkbox so the code blocks work]
Posted 7-Feb-12 5:58am
Edited 7-Feb-12 8:57am
Kschuler32.9K
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

What do your mean "interrupting"? Invocation is the method to delegate some processing to a UI thread. All the delegate instances and their call parameters are queued (be the calls to Invoke or BeginInvoke) to be executed on the UI thread only. In this way, you add some workload to a UI thread, and this is absolutely unavoidable, as soon as you want to use some controls added to the UI, update the view, etc.
 
All you can do is to minimize the total volume of work by preprocessing of everything not directly related to methods or properties of the UI control in your UI-thread.
 
In you non-UI thread you can save some performance: don't call InvokeRequired — it will always return true of called not from the IO thread.
 
Accumulating of several calls in one "bigger" Invoke or BeginInvoke would not help, because they queue the data and delegate instances anyway. Just the opposite, it can degrade performance due to unwanted overhead.
 
For more detail in invocation, please see my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].
 
See also my short Tips & Tricks article for invocation to non-UI thread: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].
 
—SA
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I would build a list of items to add in my thread, return it and then bind the control to the list. You're making a loop of invoke calls, one per item, which does not seem efficient, to me.
  Permalink  
Comments
Edson Rodrigues da Silva at 7-Feb-12 11:46am
   
My application will receive data from serial port and these data should be displayed constantly in form, so I call the update method on each loop. And I need this method to be done in a thread so that I can have a button that stops the communication with the serial port anytime.
This example is just for me to learn to do it.
How can I do this without interrupting the main program?
Christian Graus at 7-Feb-12 12:04pm
   
Your best bet is probably then to build a list of a certain number of items and THEN do an update, so your thread is not constantly hammering the main one.
SAKryukov at 7-Feb-12 17:38pm
   
Cristian, unfortunately this trick cannot really help, by the reasons I explain in my answer -- please see.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 386
1 Marcin Kozub 225
2 Sergey Alexandrovich Kryukov 215
3 /\jmot 189
4 Praneet Nadkar 173
0 OriginalGriff 8,289
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,624
3 Maciej Los 4,989
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web02 | 2.8.1411023.1 | Last Updated 7 Feb 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100