问题
I have a rather long-running process in a Windows Service that periodically throws a "ContextSwitchDeadlock" exception:
I have also rigged my service to send myself emails with details about encountered exceptions. I get:
Date: 05/25/2016 09:16:32:
Exception message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
Exception Source: .Net SqlClient Data Provider
...and then three seconds later this:
Date: 05/25/2016 09:16:35:
Exception message: Cannot find table 0.
Exception Source: System.Data
BTW: At least it's consistent: I have had three pairs of those exceptions, and each time the second one is datetimed exactly three seconds after the first.
I have had prior experience with jimmying the SQLCommand's CommandTimeout value (currently set at 360) this way or that, and it seems sort of like throwing darts blindfolded or even black magic. Is there a better way to prevent such deadlocks?
I have other very similar methods that don't cause this problem; those take less time. The duration of the method (specifically, the length of time it takes the query to run) seems to be "the rub." I can't change that - "it is what it is" - so what else can I do?
UPDATE
Naturally, the recalcitrant process "made a liar out of me" right after posting the above, as I got two more pairs of the exceptions, this time with the second err msg of the pair occurring one second after the first instead of three. If I wait long enough, maybe the second exception will occur before the first one.
回答1:
The ContextSwitchDeadlock is a "Managed debugging assistant" in Visual Studio and is one of many tools that the Visual Studio debugger gives you additional aid when debugging an application.
I am not 100% positive what kind of heuristics it uses to figure out when to trigger but I know some, and this is also described in the tool window itself:
The current thread is not currently running code or the call stack could not be obtained.
This last part is what usually trips up Visual Studio and this is usually something that happens when a managed (.NET) program calls into COM or P/Invoke. When this is done, Visual Studio is no longer able to look at the program and figure out what it is doing, and when this happens to take more than 60 seconds, it figures something has gone awry.
If your program is doing the above, calling into COM, or using P/Invoke, or something involving an external non-managed (.NET) code, and this external code takes more than 60 seconds to execute, then the dialog is basically a false positive. If you know that this is benign, as in, "yes, it calls external code, and yes, this may sometimes take more than 60 seconds" then you can remove the check lower in that image:
[ ] Break when this exception type is thrown
Note that it is not necessarily an exception though, this is more Visual Studio just raising a red flag on suspicious (to it) behavior. If you know this is OK, just tell it to stop raising that flag.
Note that this has nothing to do with the other real exceptions you mention in the question, only the big ContextSwitchDeadlock dialog.
来源:https://stackoverflow.com/questions/37443014/what-would-cause-how-can-i-prevent-a-contextswitchdeadlock