GUI Thread in C#

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • bobido
    New Member
    • Feb 2008
    • 13

    GUI Thread in C#

    Hi there,

    Iam trying to make an app that has about 14 different threads which have to access the GUI and update some of the labels. Now if i do that, after a little whil it kinda hangs, I think its becaus the gui has been accesed by two or more threads at the same time. So i tried to solve this writing this code:

    Code:
            private void SetText(string text, Label item)
            {
                    if (item.InvokeRequired)
                    {
                        lock (myLockObject)
                        {
                            SetTextCallback d = new SetTextCallback(SetText);
                            this.Invoke(d, new object[] { text, item });
                        }
                    }
    
                    else
                    {
                        lock (myLockObject2)
                        {
                            item.Text = text;
                        }
                    }
                
            }
    The problem is when i trie to run this it will still hang becaus there are two different lock objects which both try to get to the gui. I also tried this:

    Code:
            private void SetText(string text, Label item)
            {
                    if (item.InvokeRequired)
                    {
                        lock (myLockObject)
                        {
                            SetTextCallback d = new SetTextCallback(SetText);
                            this.Invoke(d, new object[] { text, item });
                        }
                    }
    
                    else
                    {
                        lock (myLockObject)
                        {
                            item.Text = text;
                        }
                    }
                
            }
    Here the whole program hangs, i think its because there is one lock object thats being used for two different codes, i also tried this:

    Code:
            private void SetText(string text, Label item)
            {
                lock (myLockObject)
                {
                    if (item.InvokeRequired)
                    {
                            SetTextCallback d = new SetTextCallback(SetText);
                            this.Invoke(d, new object[] { text, item });
                    }
    
                    else
                    {
                            item.Text = text;
                    }
                }
                
            }
    And this also makes the app hang =(. So my question is how to solve this? or do i rly have to use a background worker on updating labels/texboxes in the gui?

    Heres an example of the time being updated in the gui:

    Code:
            private void tijd()
            {
                while (stoppen == 0)
                {
                    System.Threading.Thread.Sleep(500);              
                    SetText(DateTime.Now.ToString(),lbl_tijd);
                }
            }
    Thx in advance =D!
  • IanWright
    New Member
    • Jan 2008
    • 179

    #2
    If I need regular updates on screen then normally I have a separate thread running in the background which updates the screen at set intervals based upon variable parameters that it has access to. Obviously these will need locking if you're changing them from multiple threads at the same time.

    I always use delegates when doing this to prevent the GUI locking up, which I believe is similar to your callback functions, so I think you're almost there.

    Just to note, I found that in one application the lock() stopped working. Having read up on it, it isn't reliable for large numbers of repetitive, successive calls (e.g. drawing), so just be careful when you are using it.

    Ian

    Comment

    • bobido
      New Member
      • Feb 2008
      • 13

      #3
      Originally posted by IanWright
      If I need regular updates on screen then normally I have a separate thread running in the background which updates the screen at set intervals based upon variable parameters that it has access to. Obviously these will need locking if you're changing them from multiple threads at the same time.

      I always use delegates when doing this to prevent the GUI locking up, which I believe is similar to your callback functions, so I think you're almost there.

      Just to note, I found that in one application the lock() stopped working. Having read up on it, it isn't reliable for large numbers of repetitive, successive calls (e.g. drawing), so just be careful when you are using it.

      Ian
      thx m8 =D. I tried another way, by putting all the data in an array and have one thread update the lbls with the data in the array. That didnt work =,(. So iam goin to try and use the backgroundworke r, which I read should be easier to work with (as long as it works for me =p)

      greetz, bobido!

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Are you calling those functions with an event or just trying to call it directly from other threads?

        Comment

        • bobido
          New Member
          • Feb 2008
          • 13

          #5
          Originally posted by Plater
          Are you calling those functions with an event or just trying to call it directly from other threads?
          They are being called on an event =)

          Comment

          • iLL
            New Member
            • Oct 2006
            • 63

            #6
            I didn't really look to close at your code, but I think you need a global Mutex lock

            Example:

            Code:
            class blah
            {
            	System.Threading.Mutex mLock;
            	
            	public blah()
            	{
            		mLock = new System.Threading.Mutex
            	}
            	
            	public void method1()
            	{
            		mLock.WaitOne();
            		// Critical Section
            		mLock.Release();
            	}
            	
            	public void method2()
            	{
            		mLock.WaitOne();
            		// Critical Section
            		mLock.Release();
            	}
            }
            Only one thread will be allowed into ether critical sections at a time

            Comment

            • iLL
              New Member
              • Oct 2006
              • 63

              #7
              After taking a little closer look at your code. I don't see how it is hanging. Here we should only worry about race conditions, and there should not be anything hanging on a race condition. Deadlocks and starvations causes hangups. Does it hang up at the same spot every time? Does it work for one or two threads? Or does it not work at all?

              Comment

              • bobido
                New Member
                • Feb 2008
                • 13

                #8
                Originally posted by iLL
                After taking a little closer look at your code. I don't see how it is hanging. Here we should only worry about race conditions, and there should not be anything hanging on a race condition. Deadlocks causes hangups. Does it hang up at the same spot every time? Does it work for one or two threads? Or does it not work at all?
                It does work with two threads. Iam using an DDE connection to an server, through a hot link. Whenever, for example, the time is being update and information comes streaming in on the same time, the dde connection will hang because it cant wait with updating (i think thats becaus it isnt a thread but an eventhandler??) . Cant i just isolate parts of my gui so that some part of the code can always access those labels, =(? Iam goin to try to make an ReaderWriterLoc k becaus the gui only needs to read the data anyway, but than the problem may still occur when two hot links activate a event on the same time. Iam running out of ideas, lol =p

                Comment

                • iLL
                  New Member
                  • Oct 2006
                  • 63

                  #9
                  Originally posted by bobido
                  It does work with two threads. Iam using an DDE connection to an server, through a hot link. Whenever, for example, the time is being update and information comes streaming in on the same time, the dde connection will hang because it cant wait with updating (i think thats becaus it isnt a thread but an eventhandler??) . Cant i just isolate parts of my gui so that some part of the code can always access those labels, =(? Iam goin to try to make an ReaderWriterLoc k becaus the gui only needs to read the data anyway, but than the problem may still occur when two hot links activate a event on the same time. Iam running out of ideas, lol =p
                  I hate to tell you this, but I have no experience with dealing dynamic data exchange.

                  But let me see of I have this correct.

                  You have some data coming through the buffer. When the data comes in, it triggers an event. When this event is triggered, some thread will update the label. Is that correct?

                  And you are using 14 threads so that you can read the data fast enough?

                  Comment

                  • iLL
                    New Member
                    • Oct 2006
                    • 63

                    #10
                    Originally posted by bobido
                    Cant i just isolate parts of my gui so that some part of the code can always access those labels
                    If every thread has access to your FormX class, I don't see why you can't make a method that updates a label. Only one thread can do this at a time.

                    You can also make a label public. This might be bad though.

                    Originally posted by bobido
                    Iam goin to try to make an ReaderWriterLoc k becaus the gui only needs to read the data anyway, but than the problem may still occur when two hot links activate a event on the same time.
                    You don't need any lock if you are only reading. As for two hot links activating an event at the same time, is that possible?

                    Comment

                    • bobido
                      New Member
                      • Feb 2008
                      • 13

                      #11
                      finally...

                      I managed to solve the problem:

                      Code:
                              public class TheContainer
                              {
                                  public static Main TheForm;
                                  public static DdeClient TheDdeClient;
                              }
                      By putting the form and the dde connection in a container? It worked :S?

                      I dont know why, can anyone tell me please =)?

                      Comment

                      Working...