2

我在 Windows 服务中有一个运行时间相当长的进程,它会定期抛出“ContextSwitchDeadlock”异常:

在此处输入图像描述

我还操纵我的服务向自己发送电子邮件,其中包含有关遇到的异常的详细信息。我得到:

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

...然后三秒钟后:

Date: 05/25/2016 09:16:35: 
Exception message: Cannot find table 0.
Exception Source: System.Data

顺便说一句:至少它是一致的:我有三对这样的异常,每次第二个的日期时间都在第一个之后的三秒。

我以前有过以这种或那种方式调整 SQLCommand 的 CommandTimeout 值(当前设置为 360)的经验,这似乎有点像蒙着眼睛扔飞镖,甚至是黑魔法。有没有更好的方法来防止这种死锁?

我有其他非常相似的方法不会导致这个问题;那些需要更少的时间。方法的持续时间(特别是查询运行所需的时间长度)似乎是“问题”。我无法改变这一点——“它就是这样”——那我还能做什么?

更新

自然地,在发布上述内容之后,顽固的过程“让我成为骗子”,因为我又得到了两对异常,这次是第二对错误消息发生在第一个而不是三个之后一秒如果我等待的时间足够长,也许第二个异常会在第一个异常之前发生。

4

1 回答 1

3

ContextSwitchDeadlock 是 Visual Studio 中的“托管调试助手”,是 Visual Studio 调试器在调试应用程序时为您提供额外帮助的众多工具之一。

我不是 100% 肯定它使用什么样的启发式方法来确定何时触发,但我知道一些,这也在工具窗口本身中进行了描述:

当前线程当前未运行代码或无法获取调用堆栈。

最后一部分通常会导致 Visual Studio 出错,这通常是托管 (.NET) 程序调用 COM 或 P/Invoke 时发生的事情。完成此操作后,Visual Studio 不再能够查看程序并弄清楚它在做什么,而当这发生超过 60 秒时,它会认为出现了问题。

如果您的程序正在执行上述操作,调用 COM,或使用 P/Invoke,或涉及外部非托管 (.NET) 代码的东西,并且此外部代码执行时间超过 60 秒,那么对话框基本上是一个假阳性。如果您知道这是良性的,例如“是的,它调用外部代码,是的,这有时可能需要超过 60 秒”,那么您可以删除该图像下方的检查:

[ ] 抛出此异常类型时中断

请注意,它不一定是一个例外,这更像是 Visual Studio 只是对可疑(对其)行为提出了一个危险信号。如果您知道这没问题,只需告诉它停止升旗。

请注意,这与您在问题中提到的其他真正例外无关,只有大的 ContextSwitchDeadlock 对话框。

于 2016-05-25T16:42:37.880 回答