This is something related to a bug which was not so reproduce able , but was seen once a week at least on one of the many test machines. We used to get a "Server busy" dialog box and Switching or Retrying did not do anything. We have to kill the application.
I was accustom to see this dialog when a COM server is busy or is waiting for some resource and usually after some time, Switching or Retrying worked.
Fortunately i got this error on my development machine once and more fortunately i was running a debug build. I paused the program and watched the call stack. The program was waiting on a thread which was in a "Wait or Sleep/Join state". Drilling down more on the thread, it was found that it was one of the our own application thread.
This information gave me a good deal of information on where to look for. I checked the module which created the thread and found that it was created in a user control and the thread was using a AutoResetEvent object. The wait state of the thread as i discovered earlier from call stack was from the Dispose call of the user control. I checked the code to see the places where the AutoResetEvent was closed or signaled. Well the object was not cleaned up/closed in the Dispose call "which was the problem".
The thread was waiting on the AutoResetEvent object and was not allowing the user control to Dispose and hence the application to close.
Learning:
1. Clean up all variables manually, don't rely on GC. GC does a good job, but we screw up our selves thinking GC will take care.
2. Use of thread and windows kernel objects like Mutex, Semaphores etc (thread synch objects) are a double edged sword. Always use them with caution.
I was accustom to see this dialog when a COM server is busy or is waiting for some resource and usually after some time, Switching or Retrying worked.
Fortunately i got this error on my development machine once and more fortunately i was running a debug build. I paused the program and watched the call stack. The program was waiting on a thread which was in a "Wait or Sleep/Join state". Drilling down more on the thread, it was found that it was one of the our own application thread.
This information gave me a good deal of information on where to look for. I checked the module which created the thread and found that it was created in a user control and the thread was using a AutoResetEvent object. The wait state of the thread as i discovered earlier from call stack was from the Dispose call of the user control. I checked the code to see the places where the AutoResetEvent was closed or signaled. Well the object was not cleaned up/closed in the Dispose call "which was the problem".
The thread was waiting on the AutoResetEvent object and was not allowing the user control to Dispose and hence the application to close.
Learning:
1. Clean up all variables manually, don't rely on GC. GC does a good job, but we screw up our selves thinking GC will take care.
2. Use of thread and windows kernel objects like Mutex, Semaphores etc (thread synch objects) are a double edged sword. Always use them with caution.
No comments:
Post a Comment