|
ms
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
ContextSwitchDeadlocksituations where I am doing a Data Reader loop, where I am processing about 40,000 records. For each record read via the data reader, I am creating another data reader to read another database table (can't join these tables - on different machines) to get additional information. I am guessing that I am getting this error message becuase the loop is taking longer the 60 seconds to complete. Here is what is said about the error "The most probable cause is that a single-threaded apartment (STA) thread is not pumping messages. The STA thread is either waiting without pumping messages or is performing lengthy operations and is not allowing the message queue to pump." I'm sorry, but I do not have a clue as to what this means. The other probable cause is a process is consuming too much memory. Not sure That this would apply to me but perhaps opening and closing 40,000 data readers is sucking up memory, although I would have expected the garbage collector to have released this memory, but perhpas because it is all within the same paragraph, the memory is not being release. I often just cancel out of the error message and continue with the process and it completes successfully, so I don't think it is a memory issue. If I do not run in debug mode, I get the same error message running in "Release" mode. I read that you can turn off the MDA errors via the config file, but this does not seem to me to be the appropriate solution to the problem... Does it? Any ideas or suggestions? Thanks in advance for your assistance!!!! OldButStillLearning,
When you opine "can't join these tables - on different machines" are you saying you can't have a SQL Statement that joins a table on a database in another server? You should be able to do this with SQL Server. It could save you a lot of pain. Peter -- Show quoteHide quoteCo-founder, Eggheadcafe.com developer portal: http://www.eggheadcafe.com UnBlog: http://petesbloggerama.blogspot.com "OldButStillLearning" wrote: > Hello, I am getting this "ContextSwitchDeadlock" error message pop up in > situations where I am doing a Data Reader loop, where I am processing about > 40,000 records. For each record read via the data reader, I am creating > another data reader to read another database table (can't join these tables - > on different machines) to get additional information. I am guessing that I > am getting this error message becuase the loop is taking longer the 60 > seconds to complete. Here is what is said about the error > "The most probable cause is that a single-threaded apartment (STA) thread is > not pumping messages. The STA thread is either waiting without pumping > messages or is performing lengthy operations and is not allowing the message > queue to pump." > > I'm sorry, but I do not have a clue as to what this means. The other > probable cause is a process is consuming too much memory. Not sure That this > would apply to me but perhaps opening and closing 40,000 data readers is > sucking up memory, although I would have expected the garbage collector to > have released this memory, but perhpas because it is all within the same > paragraph, the memory is not being release. I often just cancel out of the > error message and continue with the process and it completes successfully, so > I don't think it is a memory issue. > If I do not run in debug mode, I get the same error message running in > "Release" mode. > > I read that you can turn off the MDA errors via the config file, but this > does not seem to me to be the appropriate solution to the problem... Does it? > > Any ideas or suggestions? > > Thanks in advance for your assistance!!!! > First, I'm assuming you hve a UI running?
If you can't do as Peter suggests, you may want to try running this process in its own thread. If you run this on a UI thread, you should move this task to an auxiliary
thread, the task blocks the pump for too long (that's why you see the MDA in debug mode). If it's not a UI thread, you should not initialize the thread as an STA thread. Willy. Show quoteHide quote "OldButStillLearning" <OldButStillLearn***@discussions.microsoft.com> wrote in message news:28E614A8-82D3-43D9-AD90-5B3FC8718267@microsoft.com... | Hello, I am getting this "ContextSwitchDeadlock" error message pop up in | situations where I am doing a Data Reader loop, where I am processing about | 40,000 records. For each record read via the data reader, I am creating | another data reader to read another database table (can't join these tables - | on different machines) to get additional information. I am guessing that I | am getting this error message becuase the loop is taking longer the 60 | seconds to complete. Here is what is said about the error | "The most probable cause is that a single-threaded apartment (STA) thread is | not pumping messages. The STA thread is either waiting without pumping | messages or is performing lengthy operations and is not allowing the message | queue to pump." | | I'm sorry, but I do not have a clue as to what this means. The other | probable cause is a process is consuming too much memory. Not sure That this | would apply to me but perhaps opening and closing 40,000 data readers is | sucking up memory, although I would have expected the garbage collector to | have released this memory, but perhpas because it is all within the same | paragraph, the memory is not being release. I often just cancel out of the | error message and continue with the process and it completes successfully, so | I don't think it is a memory issue. | If I do not run in debug mode, I get the same error message running in | "Release" mode. | | I read that you can turn off the MDA errors via the config file, but this | does not seem to me to be the appropriate solution to the problem... Does it? | | Any ideas or suggestions? | | Thanks in advance for your assistance!!!! | The tables being accessed are Oracle, and while I could interject SQL Server
into the equation, I think this overly complicates things and I'm not exactly sure why I would not run into the same issue. I am not creating a seperate thread for this processing, but if I do this, I'm still not quite sure how this aleviates the problem? Why would placing this process in its' own thread now eliminate the error message that the process is taking longer the 60 seconds? Even if I place the process in another thread, it will still take longer then 60 seconds, so how does this solve the problem? If I resorted to introducing SQL Server and called a stored procedure which invoked a DTS package, that process would, as well, take longer then 60 seconds, so how would interjecting SQL server help resolve the problem either? Thanks in advance for your assistance.
Show quote
Hide quote
"OldButStillLearning" <OldButStillLearn***@discussions.microsoft.com> wrote Well, actually you didn't answer the question why you run this on an UI in message news:013119B9-6434-4D14-8BDD-EB823FA9C6C4@microsoft.com... | The tables being accessed are Oracle, and while I could interject SQL Server | into the equation, I think this overly complicates things and I'm not exactly | sure why I would not run into the same issue. | | I am not creating a seperate thread for this processing, but if I do this, | I'm still not quite sure how this aleviates the problem? Why would placing | this process in its' own thread now eliminate the error message that the | process is taking longer the 60 seconds? Even if I place the process in | another thread, it will still take longer then 60 seconds, so how does this | solve the problem? | | If I resorted to introducing SQL Server and called a stored procedure which | invoked a DTS package, that process would, as well, take longer then 60 | seconds, so how would interjecting SQL server help resolve the problem either? | | Thanks in advance for your assistance. | (STA) thread, but I assume it's the case. The UI (STA) thread has a message queue that needs to get 'pumped' in a timely fashion, the CLR (in debug mode only) will inject a ContextSwitchDeadlock" exception when you fail to pump once per 60 secs. So, if you want to: - get rid of this MDA and, - if you want your UI thread to stay responsive (which is not the case if you block the pump), and optionally - if you don't want to take the risk to block the finalizer thread in COM scenarios. you will have to move the task to another thread which doesn't have a message queue, that is to a non UI non STA thread. Willy. Thanks Willy, I have no real experience with thread, so I did not answer the
question, because I was not sure how to answer. I did indicate that I had not created a thread to run this process on, which I was hoping would answer the question as to if it was being run on a "UI (STA) thread". So If I have not created a thread, then my assumption was that I was using the "UI (STA) thread". So is that a good assumption? As I mentioned, I have no experience in creating or running threads, but I am looking at an example. Basically, I create a class which has a run method which does all the processing that I want to have done within the thread, and I create an instance of that class in my main procedure and then invoke the run method. Is that about right? But I'm guessing that I need to do something in the main procedure to "wait" for the "thread to finish" as if I don't my procedure will terminate the program. To do this, would I use the Thread.Sleep(XXXXX) within a while loop, which continues to test if my "thread" is still "alive"? I created the "IsAlive" propery in my "thread" class, but it will not complile, I get a "'BatchJobs.SQLThread.IsAlive.get' must declare a body because it is not marked abstract or extern" when I place this "Property in my thread class "public bool IsAlive { get; }" So is this what I should be doing? What am I doing wrong? Again, Thanks so much for your help!!!!
Show quote
Hide quote
"OldButStillLearning" <OldButStillLearn***@discussions.microsoft.com> wrote Ok, let me ask whether your application is a windows (Forms) application or in message news:91CC4037-4E25-4C25-B550-7044A9DBF1BC@microsoft.com... | Thanks Willy, I have no real experience with thread, so I did not answer the | question, because I was not sure how to answer. I did indicate that I had | not created a thread to run this process on, which I was hoping would answer | the question as to if it was being run on a "UI (STA) thread". So If I have | not created a thread, then my assumption was that I was using the "UI (STA) | thread". So is that a good assumption? | | As I mentioned, I have no experience in creating or running threads, but I | am looking at an example. Basically, I create a class which has a run method | which does all the processing that I want to have done within the thread, and | I create an instance of that class in my main procedure and then invoke the | run method. Is that about right? But I'm guessing that I need to do | something in the main procedure to "wait" for the "thread to finish" as if I | don't my procedure will terminate the program. | | To do this, would I use the Thread.Sleep(XXXXX) within a while loop, which | continues to test if my "thread" is still "alive"? I created the "IsAlive" | propery in my "thread" class, but it will not complile, I get a | "'BatchJobs.SQLThread.IsAlive.get' must declare a body because it is not | marked abstract or extern" when I place this "Property in my thread class | "public bool IsAlive { get; }" | | So is this what I should be doing? What am I doing wrong? | | Again, Thanks so much for your help!!!! | | a Console style application. If it's the former, your main thread is the UI thread and this thread has to pump the message queue in a regular fashion, if it's the latter, your main thread is not a UI thread and should not run in an STA, that is, you should not decorate the Main entry with STAThreaAttribute in order to get rid of the MDA. In the case of a windows application, you need to create a thread to run your Run method. You don't have to wait for the thread procedure to finish, especially don't call sleep in your UI thread, 'Sleep' blocks the thread for the duration of the sleep time, something you should never do in an UI thread. Let your Run method update the UI when it runs to an end, note however that you need to marshal the update call to the UI thread by calling Control.Invoke or Control.BeginInvoke from the Run method. Please search MSDN for details on the Thread class, Control class and BackgroundWorker etc... Willy. My application is a console application.
So I can't tell if the statement "not decorate the Main entry with STAThreaAttribute in order to get rid of the MDA" means? Is this saying that I do not need another thread to resolve the issue? "OldButStillLearning" <OldButStillLearn***@discussions.microsoft.com> wrote Ok, we are getting closer, seems like the Oracle provider in message news:70D52C36-7DCC-4CB4-8D1A-D48B226FAF97@microsoft.com... | My application is a console application. | | So I can't tell if the statement "not decorate the Main entry with | STAThreaAttribute in order to get rid of the MDA" means? Is this saying that | I do not need another thread to resolve the issue? (System.Data.OracleClient ?) is using COM interop, question is what are his threading requirements. If you have a Main method that has the STAThread attribute, something like this: [STAThread] int Main(...) ..... remove the [STAThread] attribute, and you're done. If you don't have such attribute, add the attribute like shown above. Note that when running in a STA, you need to pump messages, that is, you may not block the pump for too long a period. To do so, you need to insert a pumping wait calls in your loop. One that comes to mind is Thread.Join(), so in your loop you simply insert: while(reader.Read()) { // process data // and pump... System.Threading.Thread.CurrentThread.Join(10); } .... This will insert a 'pumping wait' in the current code path for ~10 msecs. Note however that this all won't work if a single DB command takes more than the MDA time-out period, if that's the case, all you can do is ignore the MDA (it should not appear when running outside of VS). Willy. I am using the Oracle drivers (Oracle.DatabaseAccess) and not the Microsoft
version of the Oracle drivers. Yes, my "Main" method had the "[STAThread]" and I removed it as you suggested. I had already modified my program to create a thread for the process which is reading and looping through the database, and I can not tell any longer if you believe that is or is not necessary. It almost sound like you think the removal of the "[STAThread]" is going to do the trick. I have been wanting to learn more about threading as it is something that I have a need for in other processes, even if it turns out I do not need it here. So by taking off the "[STAThread]", the system no longer is checking the "pump" period? Is that the gist of what is occuring? My test ran successfully and was not been interupted by the "ContextSwitchDeadlock" error message, so it would appear that the issue is resolved, but I'm not sure which action resolved it, changing the process to run on its' own thread or removing the "[STAThread]", but I suspect that it was the ""[STAThread]" change. Again, thanks SOO MUCH FOR YOUR HELP!!!!!! The STAThread attribute on Main initializes the main thread to enter a
Single Threaded Apartment (STA). STA threads need a message queue to synchronize it's accesses, if a thread doesn't run a message queue when it enters the STA, COM will create one on your behalf, but it's up to your code to pump the messages. Now, without STAThread, the thread remains uninitialized or enters the MTA and no queue gets created, effectively removing the requirement for "pumping". That's why you won't see the MDA again. Willy. Show quoteHide quote "OldButStillLearning" <OldButStillLearn***@discussions.microsoft.com> wrote in message news:FF1F78B3-42A6-4398-ABA9-B9535DF46F5A@microsoft.com... |I am using the Oracle drivers (Oracle.DatabaseAccess) and not the Microsoft | version of the Oracle drivers. | Yes, my "Main" method had the "[STAThread]" and I removed it as you | suggested. I had already modified my program to create a thread for the | process which is reading and looping through the database, and I can not tell | any longer if you believe that is or is not necessary. It almost sound like | you think the removal of the "[STAThread]" is going to do the trick. I have | been wanting to learn more about threading as it is something that I have a | need for in other processes, even if it turns out I do not need it here. | | So by taking off the "[STAThread]", the system no longer is checking the | "pump" period? Is that the gist of what is occuring? | | My test ran successfully and was not been interupted by the | "ContextSwitchDeadlock" error message, so it would appear that the issue is | resolved, but I'm not sure which action resolved it, changing the process to | run on its' own thread or removing the "[STAThread]", but I suspect that it | was the ""[STAThread]" change. | | Again, thanks SOO MUCH FOR YOUR HELP!!!!!! | OK, I thought the IDE generated the "STAThread" when it created the class for
me, but maybe not, because I have done a lot of maintenance on it and perhaps I copied something from another class. I can't say for sure. So what is a message que and when do I need one, as I apparently do not need one in this instance..... The message queue (I believe) is how windows tells your application
which events are raised. So your application may get a messge asking it to refresh, handle a user click event, etc. While you are working in the main thread, your UI can't respond to those events until your code completes. Build a windows forms application, and add a button to a form. IN the button click handler, add a System.Threading.Thread.CurrentThread.Sleep( 10000 ) call. Then try to move the form or drag another window over it, and notice it doesn't repaint. Eventually the thread will 'wake up' and handle the events (Paint, Move, etc). Unless you explicitly create another thread, you're always working on the main thread. Sounds like using the STAThread attribute will automatically create a message queue (aka message pump) on the main thread. Working with threads is fairly easy, but can also be easy to mess up. If you're doing a Windows form application you probably will want to use the BackgroundWorkerProcess component. It will handle a background thread so that your UI can continue to update smoothly. It works by creating an event handler for the components DoWork event. The code in here is the code that will actually execute on a background thread. In the DoWork event handler, you can raise another event to report progress back to your ui. The UI will remain responsive instead of blocking using this component.
Other interesting topics
Property accessors and Optimization
static controls Return month from dropdown as integer Some construction that I don't understand why it works as it does. Adding auditory feedback to button clicks Interesting flickering problem if application's user control is invalidated by external application Data binding an array to a listbox "The page cannot be displayed" when running web service REGEX vs Stack Tokenizer? WindowsIdentity and Non-AD directory services |
|||||||||||||||||||||||