Thread problem with GUI user control by using raiseevent

Dear All,

I have a program which have a main thread to keep updating a object. When the object's properties is being updated. It raiseevent and I have several user control will handles the object's event using Invoke with Delegation.

However, under some situation such as I close one form which contains the user control which is associated with the object's event. Sometimes it will make the main thread corrupts which can not update the object properties anymore. My primary suspection is whe the main thread is trying to raiseevet, the other hand the I close the form. The user control is closed so the main thread is being blocked by this action. So I try to use BeginInvoke to replace Invoke to avoid the blocking for the main thread and it seems work that the problem didn't happen again for several days (It happens 1 - 2 times a day before)

However, the problem is not totally solved. The main thread still hangs sometime. Can anyone kindly give me some insight about this problem I sincerely thank for all of your kindly help.




Answer this question

Thread problem with GUI user control by using raiseevent

  • redshock

    Multithreading: you have to understand that to really appreciate the problem.

    Replacing an invoke with begininvoke, or specifically visa versa, does not make the problem go away. It sounds like as you are invoking across from one thread to the other, after determinimng that invokation is required, the GUI handle has gone, so you can't invoke. Usually, I've seen the result being a crash, rather than hanging, so it's possible that you have something else going on. I'm sure it has something like that going on - since you are destroying controls which are being accessed by another thread.

    A solution may be is to have a 'pull' mechanism rather than a 'push' mechanism: specifically, the control gets the information from the 'main thread' - a simple timer event can work. Or, you can use a proxy object which handles the marshalling from one thread to another. This is helpful when you have a lot of marshalling required, you can concentrate the handling of the issues in a single location. This may involve some kind of interlocking, still. However, the invoke commands on a control are thread safe, but only that call e.g. if you call InvokeRequired, then BegnInvoke, the call sequence is obviously not thread-safe. (i'm assuming thatb it's a control which inherits from the 'control' class).

    Does any of that help



  • connect2sandeep

    I am sorry for make you feel confusing. Let's say I have two thread. Thread A will continue receive some XML message and update object A's properties according to the content of the XML message. When its properties is changed, it raise event using raiseevent and I have several usercontrol will handle the events raise from the object.

    The problem I found is when user close the form with the user control and Thread A is raising raiseevent. It make Thread A hangs and stop process XML message. That's why I suspect this is cause by using Invoke which block Thread A. Then I replace the handler inside the user control by BeginInvoke. And the number of occureces drop from one day several times to only one time so far as reported by user. Hope that you can understand what I meant. Thanks!



  • RajLakamana

    I'm a bit confused as to what is updating what: what can you show which will demonstrate the problem Are you using BeginInvoke, or Invoke Which one causes the problem What does the other one do



  • Nilesh Ingale

    I don't think switchng between Invoke and BeginInvoke is going to solve the problem. At some point, the event is going to be raised while the form exists, then while you are invoking the form goes away, and you get the problem. The timing has to be right to cause it, but it's there nonetheless.

    It certainly sounds like a synchronization problem. How about prior to raising the event, or even mashalling, checking a flag to see if the form is present (from your description it appears that the form may come and go, while the thread continues to be active). Set the flag when the form is closing.

    I'm not convinced that will solve it (I'd have to think about it some more), but you need a mechanism to stop raising events on a form which is 'going away' (being closed).

    When you say the application 'hangs', are you saying it stops responding It's getting difficult to diagnose the problem without seeing some code...



  • onderkoksal

    Replacing an invoke with begininvoke, or specifically visa versa, does not make the problem go away. It sounds like as you are invoking across from one thread to the other, after determinimng that invokation is required, the GUI handle has gone, so you can't invoke. Usually, I've seen the result being a crash, rather than hanging, so it's possible that you have something else going on. I'm sure it has something like that going on - since you are destroying controls which are being accessed by another thread.

    It will throw exception when the GUI handle has gone but the problem is the main thread didn't throw any exception but hangs which cannot continue to update the object's properties by deque the information from a message Queue. (Main thread will continue deque message from a message queue to update the object normally) That's why I think it may be the problem of I use Invoke which block the main thread if the GUI handle has gone and replace it with BeginInvoke to prevent making the main thread hangs. Is it a possible way



  • Andy Pham

    Since the form is being closed controlled by the user, how can I set the flag to stop the raiseevent from the main thread when the GUI form is closing by checking a flag

    The 'hangs' problem of the main thread sounds like it stops responding to process information update of the objects thus user didn't see any information update in the GUI form when the form is open again or the form is not being closed which is showing the object's properties information.



  • Spanglishone

    Is it mean I need to place a timer on the GUI form to schedule update the information from the object to the GUI display with certain interval



  • Thread problem with GUI user control by using raiseevent