84

I am running a C# application, and during run-time I get the following error:

The CLR has been unable to transition from COM context 0x20e480 to COM context 0x20e5f0 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

Can anyone please help me out with the problem here?

Thanks a lot.

JYelton
  • 35,664
  • 27
  • 132
  • 191
assassin
  • 19,899
  • 10
  • 30
  • 43

9 Answers9

126

The main thread of your program has been busy executing code for a minute. It is not taking care of its normal duties, pumping the message loop. That's illegal when you use COM servers in a worker thread: calls to their methods cannot be dispatched until your main thread goes idle again.

It should be readily visible, your UI should be dead as a door nail. Windows should have replaced your main window with a ghost that displays "Not Responding". Closing the window won't work, no click events have any effect.

Whatever your main thread is doing should be done by a worker thread instead. The BackgroundWorker class is good for that, you'll find many usage help in the MSDN Library article for it. Use Debug + Break All, Debug + Windows + Threads if you have no idea what the main thread is doing.

One more possible cause: be sure to install service pack 1 if you are using the RTM version of VS2005.

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 5
    +1 for explaining that such a work item should be moved to a secondary thread, thus the solution on how to avoid this error (rather than just what produces the error). – JYelton Mar 21 '11 at 22:35
  • 2
    Interesting that I have seen a few other in-house built applications hang for much longer than mine did yet I hit this error message, hmmm. – Paul C Nov 22 '12 at 16:27
  • MSDN Documentation: contextSwitchDeadlock MDA http://msdn.microsoft.com/en-us/library/ms172233%28v=vs.110%29.aspx – D_Bester Oct 22 '14 at 05:35
  • 1
    Thanks for the detailed explanation The workarounds I have used are async functions, which now makes perfect sense. So, from what I gather, it is very important to manage a new thread for long running operations, especially when utilizing COM. – Anthony Mason Oct 24 '16 at 19:17
50

To find which operation is blocking the context switch and causing the contextSwitchDeadlock MDA to be displayed, you can use the following steps. Note that I will be referring to Visual Studio 2012.

  1. Reproduce the error. This could involve some trial and error.
  2. Click 'OK' rather than 'Continue' in the Managed Debugging assistant which is displayed.
  3. Ensure that the Debug Location toolbar is active by right clicking on the toolbar docking region and selecting 'Debug Location'. You should see a drop down list labelled 'Thread' in the toolbar if it is active.
  4. The selected item in the Thread drop down list should be a thread other than the main thread as it will be a background thread that is complaining that the main thread is hogging all of the attention. Select the main thread in the drop down list.
  5. You should now see the code that is blocking the context switch in the code editor.

Assuming that you decide against moving the resource intensive operation off your main thread - take a look at some of the other answers and comments here before you do - you have the following options to disable the Managed Debugging Assistants.

Within the Visual Studio Debugger

  1. You can disable an MDA directly in the MDA dialog that is displayed when the error occurs by unchecking 'Break when this exception type is thrown'.
  2. With Exception Settings dialog using the instructions below from MSDN.

...on the Debug menu, click Exceptions. (If the Debug menu does not contain an Exceptions command, click Customize on the Tools menu to add it.) In the Exceptions dialog box, expand the Managed Debugging Assistants list, and then clear the Thrown check box for the individual MDA.

Outside the Visual Studio Debugger

  1. Registry Key (Machine Wide, All MDAs affected)
  2. Environment Variable (Machine Wide, MDAs can be specified)
  3. Application Configuration Settings (Application scope, MDAs can be specified)

Note: One of the first two options must be set to 1 for the third to have any effect.

In my case, the problem was a call to ObjectContext.SaveChanges() in the Entity Framework within a console application. With the MTAThreadAttribute applied to the Main() method the ContextSwitchDeadlock exception was no longer raised. I am unfortunately unsure of the full affects of this change.

Scott Munro
  • 13,369
  • 3
  • 74
  • 80
11

This message indicates that some code of yours is trying to switch threads, and the target thread is busy. For example, a background thread trying to dispatch a call to the UI thread to update the UI, while the UI is running a tight loop for a while.

To actually figure out what's going on you need to break into the debugger and look at all the threads and what they are doing.

Franci Penov
  • 74,861
  • 18
  • 132
  • 169
4

In some cases :
Debug -> Exceptions -> Managed Debug Assistants
and unchecking the ContextSwitchDeadlock item.

Ehsan Zargar Ershadi
  • 24,115
  • 17
  • 65
  • 95
  • Maybe if you were incredibly desperate but as a I high priority should go back and fix it – Paul C Nov 22 '12 at 16:32
  • 5
    Yes, but when you're writing a one off test and this gets in your way, its nice to be able to disable it. – Tod May 07 '13 at 21:41
  • 4
    No. Wrong. This is not a solution to the problem. – Tom W Oct 03 '13 at 13:27
  • 5
    You got to think like an engineer not an scientist!! – Ehsan Zargar Ershadi Oct 06 '13 at 09:46
  • 4
    @Ehsan Ershadi, a good engineer anticipates and fixes problems, not push it under the carpet! – Mo Patel Nov 12 '13 at 09:57
  • 4
    LOL. If you don't wanna see the error, you can simply look somewhere else other than your monitor. This is the same approach with your "solution" . This is not a solution. This is just IGNORING! – curiousBoy Mar 17 '14 at 23:30
  • Keep in mind, guys, this is only a warning, it's not necessarily indicative of a real problem. -- Disabling the MDA globally though is kind of lame, because there may be a future warning for a different block of code, that *is* indicative of a real problem, and you won't see it. It would be nice if there was a way to do a one-off suppression in code, with a justification link (like you can with other warnings). – BrainSlugs83 Jul 11 '16 at 18:08
0

I ran into this issue when I was trying to figure out why my OracleDataReader was throwing an exception. I thought it was because it was getting assigned null because the exception was related to a parameter that was `null. So I did:

while (dr.Read())
{
    while (dr != null)  // <-- added this line
    {
      ...

Turned out the dr was NEVER null and so the loop just went on and on until this message arrived, and on and on some more because you can click "Continue" to keep it going until you run out of memory (don't do this - click "OK" instead). So moral of the story, look for memory leaks that are streaming data from the database into memory in loops to infinity. The error is actually trying to warn you of a bad scenario. Best to heed it.

vapcguy
  • 7,097
  • 1
  • 56
  • 52
0

This error came up for me numerous times, and I traced it down to an iteration in DataGridViewRow, in which I set the checkbox value to true. Since I was running in debug mode, I had the option to continue, so I was able to do just this.

I hope this helps someone.

Just Rudy
  • 700
  • 11
  • 28
0

Finally, I found a working solution for my vb.net Windows Application Form

Application.DoEvents()

Statement somewhere within the loop.

Reference: https://earlybites.wordpress.com/2012/04/10/resolution-context-switch-deadlock-was-detected/

Ram
  • 131
  • 8
0

Simply select Exceptions from the Debug menu in the visual studio 2005 window , the Edxception Dialog box wil popup , select the Managed Debugging Assistants Exception Node , then select ContextSwitchDeadlock and remove the select from Thrown column . this will stop the vs from throwing the ContextSwitchDeadlock exception.

Hope this helps..

  • 60
    Your arm is on fire. Simply use a knife to cut the nerve which sends pain to your brain. This will stop you noticing that your arm is on fire. – Ozzah May 09 '12 at 01:52
  • Any way this is a way to solve the problem temporarily. To complete cut this problem off, need some time to reconsider about the design of application. – Wang Jijun May 26 '17 at 07:21
-1

Assuming you are using Visual Studio, you can click Ctrl+Alt+E in the current project and exceptions window will display with select Managed Debugging Assistants you should uncheck the "ContextSwitchDeadlock" option. then build a current project.

Cleptus
  • 3,446
  • 4
  • 28
  • 34
  • It just skips the exception, but question is explanation about the issue or resolution .. not work around. – HydTechie Jan 22 '21 at 09:54