WaltN's picture

A Little More on ContextSwitchDeadlock

I encountered the ContextSwitchDeadlock exception for the first time yesterday when I viewed a 256 x 256 terrain for the first time with my experimental viewer. (Previously was only a 16 x 16 test case.) The model was rotating at a constant rate. No other libraries are involved -- no XML, WCF, etc. My Main is decorated with [STAThread].

I don't know why I tried this, but, normally running with VSyncMode.On, I turned it off. The exception went away. I turned VSync back on, and the exception came back. That makes no sense to me.

More mysterious, this morning, I can't make it fail. VSync is on. I don't know what's different. I certainly didn't touch the code; spent all my time this morning searching and reading the forum.

I expect that the problem will reappear at some time. If it does reappear, I can send my project, which is only 3.3M zipped.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Luage's picture

EDIT: NEVERMIND,THIS DOESN FIX IT

I know this answer comes bit late but it might help someone else :/

I added
base.OnLoad(e);
to the override OnLoad funktion I used, and simlar "base." funktion calls to every other override I used.
This seems to have fixed it though I can't really be sure. It feels like a very inconsitent error.

the Fiddler's picture

Try defining the [STAThread] attribute on your Main function:

[STAThread]
void Main(string[] args)
{
    ...
}
Luage's picture

It was there in my main function when it threw the error for me.

And doing some further testing tells me that the suggestion i gave above doesnt fix it either. But the crash is very inconsistent... sometimes the application runs for half an hour without any problems and othertimes it crashes within 60 seconds from launching.

Luage's picture

Hmm. It seems that I have no idea how to fix this after all. Here is the error message I get:

Quote:

ContextSwitchDeadlock was detected
Message: CLR kan ikke skifte fra COM-konteksten 0x2b8a80 til COM-konteksten 0x2b8bf0 i 60 sekunder. Tråden, der ejer destinationskonteksten/apartment'en udfører højst sandsynligt enten en venten uden at pumpe eller behandler en meget lang kørselshandling uden at pumpe Windows-meddelelser. Denne situation har generelt en negativ indflydelse på ydeevnen og kan tilmed føre til, at programmet ikke svarer, eller at hukommelsesforbruget akkumulerer kontinuerligt med tiden. For at undgå problemet skal alle enkelttrådede apartmenttråde (STA) bruge pumpende wait-primitiver (såsom CoWaitForMultipleHandles) og rutinemæssigt pumpe meddelelser under lange kørselshandlinger.

Roughly translated

Quote:

ContextSwitchDeadlock was detected
Message: CLR can not change from the COM context 0x2b8a80 to the COM context 0x2b8bf0 in 60 seconds. The thread that owns the destination context/apartment is likely either performing a waiting without pumping or performing a very long task without pumping Windows-messages. This situation in general has a bad influence on performance and can even cause the application to not respond, or the memory use to accumulate over time. To avoid the problem all singe threaded apartments (STA) have to use pumping wait-primitives (such as CoWaitForMultipleHandles) and routinely pump messages under long tasks.

the Fiddler's picture

Is this problem reproducible using e.g. the QuickStart sample in the OpenTK folder?

Which version of OpenTK are you using? Your GPU model, drivers and Windows version would also be helpful so I can try to reproduce this.

Luage's picture

I will try to see if I can reproduce this on the QuickStart sample, but as I mentioned earlier it is very inconsistent and right now I have been running my main application for a total of more than two hours since I last saw the error there.

OpenTK version: 1.0 (the one suggested on the front page)
GPU model: Intel 3000
Drivers: Build 9.17.10.3223
Windows: Windows 7 Home Premium

Other things to note: I am using the XNA library to take input from an Xbox 360 controller

And one more thing. I tried to add:
System.Windows.Forms.Application.DoEvents();
to the beginning of my OnUpdateFrame function.
While having zero impact on framerate (to any degree that I can measure at least) this had the effect that when my application is in the background all other windows applications respond faster. (specifically: changing focus from my application to Visual C# takes about three seconds when the DoEvents call is not present, but happens almost instantaneously when it is. Also Windows UI effects, such as changing the color of an icon on the task bar while hovering over it, only happens when DoEvents is present, otherwise windows seems totally inresponsive, but in a way it is. Opening the "task manager" always happens straight away.)
I haven't seen the error since adding that either, but that might as well be coincidence, just something to note.

EDIT:
Ok. The situation with DoEvents seems to be more complex than I implied above. Here is what I think I have found:

With DoEvents call: Windows UI always responsive.

Without DoEvents call: Some windows functions always responsive (such as the task manager) others might or might not be responsive. When the the application has just started up the taskbar at the bottom of the screen in never responsive. It might become responsive within a few seconds, or it might not. Dragging the application window reactivates the taskbar which is now fully responsive, however changing focus of a program does not have this effect.

Luage's picture

Double edit:
Adding System.Windows.Forms.Application.DoEvents(); to my update event seems to have actually improved my framerate.. At least when rendering objects with many vertexes
Still no sign of the error message today

Luage's picture

Triple edit:
Tried to launch the quick start example. It threw an error until I replaced
GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
with
GL.Viewport(0, 0, Width, Height);

Then it drew everything as it should, but exhibited the same behavior that I described above. Three second delay in windows actions.

I haven't seen the "ContextSwitchDeadlock" error yet.

Luage's picture

I think I might have tracked down the problem.
My computer runs a Danish version of Windows which mean that a little side application is installed and told to run all the time. This side application allows me to change keyboard state between Danish and English. This is done through a little icon on the taskbar.

When I start a gamewindow application, even the QuickStart sample, my taskbar is frozen for between three and four seconds. Then the little keyboard icon mentioned above disappears (presumably crashed and shut down by windows) and everything is responsive again.
If i put focus on another program or on the taskbar the little icon pops up again, and if i put focus back on the gamewindow application the taskbar is frozen again for between three and four seconds.

If I add the call to DoEvents, then the little icon never disappears and everything is responsive all the time.

This would also explain why we are so few who are affected by this error.

the Fiddler's picture

Thanks, this gives me a lead on how to track down this issue.

The three second delay is definitely abnormal. I will install a non-English version of Windows to see if I can reproduce this. There is a good chance that it has something to do with incorrect IME handling.

(That said, I am always running the keyboard-layout applet and I can't say that I have ever encountered this crashing behavior.)

If you are using OpenTK.GameWindow, consider giving the SDL2 backend a try (https://github.com/thefiddler/opentk):

  1. Use OpenTK.sln to compile OpenTK.dll
  2. Build your app using the new OpenTK.dll
  3. Copy SDL2.dll into your application directory

You can find SDL2.dll under opentk/Dependencies/x86 or opentk/Dependencies/x64.

If this works without issue then (a) the problem lies definitely in OpenTK.Platform.Windows and (b) you have a working solution until this can be fixed.