【问题标题】:Halt Linq query if it will take 'too' long如果需要“太”长时间,则停止 Linq 查询
【发布时间】:2026-01-24 23:25:01
【问题描述】:

目前,我需要创建一个报告程序,该程序在 SQL 数据库中的许多不同表上运行报告。多个不同的客户端需要此功能,但一些客户端的数据库比其他客户端大。我想知道的是,如果查询时间“太长”,是否可以在一段时间后停止查询。

为了提供一些上下文,一些客户端的表超过 200 万行,尽管不同的客户端在同一个表中可能只有 50k 行。我希望能够运行查询 20 秒,如果它还没有完成,那么向用户返回一条消息,说结果集太大,需要像我们一样在几个小时之外生成报告不想在白天运行资源密集型操作。

【问题讨论】:

    标签: c# asp.net .net linq linq-to-sql


    【解决方案1】:

    通过CommandTimeoutproperty 在连接字符串或DataContext 上设置连接超时。超时后,您将收到TimeoutException,您的查询将被取消。

    您不能确定查询在超时发生的那一刻就在服务器上被取消,但在大多数情况下,它会很快取消。详情请阅读优秀文章"There's no such thing as a query timeout..."。重要的部分是:

    客户端使用注意向服务器发送查询超时信号 事件。注意事件只是一种不同类型的 TDS 数据包 SQL Server 客户端可以发送给它。除了连接/断开, T-SQL 批处理和 RPC 事件,客户端可以向 服务器。注意告诉服务器取消连接 当前正在尽快执行查询(如果有的话)。一个 注意不会回滚打开的事务,也不会停止 当前正在执行查询 - 服务器中止它 正在为下一个可用的机会进行连接。 通常,这会很快发生,但并非总是如此。

    但请记住,它会因提供商而异,甚至可能会在服务器版本之间发生变化。

    【讨论】:

    • 这实际上是取消查询,还是只是断开客户端连接?
    • 啊,谁在乎查询,那只是服务器资源。
    • 它会很可能在很短的时间内取消查询;查看更新的答案。
    • 感谢@driis 的回答。我最初正在考虑这样的事情,但几乎只是希望有人澄清。似乎它可能比线程更容易处理。
    【解决方案2】:

    如果您在后台线程上运行查询,您可以轻松地做到这一点。让主线程启动一个计时器并生成一个运行查询的后台线程。如果超过 20 秒后台线程没有返回结果,主线程可以取消它。

    【讨论】:

    • 似乎更容易使用内置超时,而不是手动使用线程。
    • 问题是不能安全地“取消”线程,尤其是在 I/O 中绑定时。