LINQ to SQL:TargetInvocationException 中包装的间歇性 AccessViolationException

Posted

技术标签:

【中文标题】LINQ to SQL:TargetInvocationException 中包装的间歇性 AccessViolationException【英文标题】:LINQ to SQL: intermittent AccessViolationException wrapped in TargetInvocationException 【发布时间】:2015-04-25 23:59:28 【问题描述】:

几周以来,我们的 ASP.Net Web 应用程序遇到了 W3WP 崩溃问题。这些是在我们的网络服务器更新后开始的。我们的应用程序没有改变,并且多年来一直很稳定。 我们的情况似乎很像this earlier question。 this question 也可能是相关的,尽管在我们的例子中,查询在 99.9% 的使用时间内运行良好。

我们使用了大量未编译的 LINQ 查询,并尝试编译它们是否可以防止这些崩溃。崩溃的数量急剧减少,但它们仍然会发生。

将我们的查询包装在try catch 中,然后捕获TargetInvocationException 也不起作用。未捕获异常。

发生崩溃时,我们会收到 WER 报告并可以检索崩溃转储。 来自未编译查询的转储的堆栈跟踪通常如下所示:

在 System.RuntimeMethodHandle.InvokeMethod(对象目标,对象 [] 参数,签名 sig,布尔构造函数) 在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象 obj,对象 [] 参数,对象 [] 参数) 在 System.Delegate.DynamicInvokeImpl(Object[] args) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInvocation(InvocationExpression 调用) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) 在 System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitExpression(Expression exp) 在 System.Data.Linq.SqlClient.QueryConverter.VisitBinary(BinaryExpression b) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.Visit(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitWhere(表达式序列,LambdaExpression 谓词) 在 System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitWhere(表达式序列,LambdaExpression 谓词) 在 System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitSelect(表达式序列,LambdaExpression 选择器) 在 System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.VisitDistinct(表达式序列) 在 System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc) 在 System.Data.Linq.SqlClient.QueryConverter.VisitInner(表达式节点) 在 System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(表达式节点) 在 System.Data.Linq.SqlClient.SqlProvider.BuildQuery(表达式查询,SqlNodeAnnotations 注释) 在 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(表达式查询) 在 System.Data.Linq.DataQuery'1.System.Collections.Generic.IEnumerable.GetEnumerator() 在 System.Linq.Buffer'1..ctor(IEnumerable'1 源) 在 System.Linq.Enumerable.ToArray[TSource](IEnumerable'1 源)

已编译查询的转储中的堆栈跟踪如下所示:

在 System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean) 在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(System.Object, System.Object[], System.Object[]) 在 System.Delegate.DynamicInvokeImpl(System.Object[]) 在 System.Data.Linq.SqlClient.SqlProvider.AssignParameters(System.Data.Common.DbCommand, System.Collections.ObjectModel.ReadOnlyCollection`1, System.Object[], System.Object) 在 System.Data.Linq.SqlClient.SqlProvider.Execute(System.Linq.Expressions.Expression,QueryInfo,System.Data.Linq.SqlClient.IObjectReaderFactory,System.Object[],System.Object[],System.Data.Linq .SqlClient.ICompiledSubQuery[], System.Object) 在 System.Data.Linq.SqlClient.SqlProvider.ExecuteAll(System.Linq.Expressions.Expression,QueryInfo[],System.Data.Linq.SqlClient.IObjectReaderFactory,System.Object[],System.Data.Linq.SqlClient.ICompiledSubQuery []) 在 System.Data.Linq.SqlClient.SqlProvider+CompiledQuery.Execute(System.Data.Linq.Provider.IProvider, System.Object[]) 在 System.Data.Linq.CompiledQuery.ExecuteQuery(System.Data.Linq.DataContext, System.Object[])

有谁知道是什么改变了我们的应用程序的行为?我们知道这是“一次更新”(但不完全是哪一次),但我们更感兴趣的是它的技术背景。 当然,我们也欢迎提供防止我们的应用程序崩溃的解决方案。

【问题讨论】:

Jacco:你有没有运气把这件事搞定?我们遇到了同样的问题,但使用的是 Windows 服务。 不,我们没有找到确切的 KB。我们正在减少崩溃的数量,并希望 MS 在另一个 KB 中修复此问题。 我们在使用 Windows 服务时遇到了同样的问题。我们只是将它从 x32 转换为 x64,我不确定这是否相关。 您的应用程序是否面向 .NET 4.5.1? 似乎问题再次浮出水面,因为您是本周第二个提出此问题的人。很抱歉,我们没有找到解决方案。我们通过编译最常用的 LINQ 查询来减少崩溃次数。对于某些人来说,这可能会有所帮助。 【参考方案1】:

我想我会发布一个解决方案,我们发现了这个问题,因为我们最近开始遇到这个问题。

我们有许多服务器可以正常运行我们的代码,但只有 1 台每周因此错误崩溃几次。我相信此服务器位于 .net 4.5.2 上。

我们向 Microsoft 开了一张票,因为他们的堆栈中发生了未处理的异常。

他们查看了我们的转储并返回了这个可行的解决方案。

一个新的修复是可用的 https://support.microsoft.com/en-us/kb/3139544

如果你迁移到 .net 4.6.1 会更好

我希望这个解决方案能帮助其他发现自己正在阅读本文的人。

【讨论】:

+1 因为这看起来与我一直遇到的问题一模一样。就像描述的那样,每天 1-3 次崩溃 - 这只是在安装 .NET 4.5.2 并且在负载较重期间才开始发生。带有 4.5.2 的节点间歇性地崩溃,没有它的节点很好。在与 MS 通话后,类似的结果 - 已知问题,建议更新到 4.6.x。【参考方案2】:

如果没有看到您的任何 Linq 代码,很难判断,但我会大胆猜测这是您正在使用的 linq 库的内部(转换)错误。

正如您提到的,您最近升级了 (您从哪个 .NET 版本升级到哪个版本?)

我有类似的问题,通过安装 Windows 更新解决了,你说你已经完成了一些结果?

尝试识别导致错误的用户输入。尝试自己处理转换,而不是依赖 Linq

【讨论】:

以上是关于LINQ to SQL:TargetInvocationException 中包装的间歇性 AccessViolationException的主要内容,如果未能解决你的问题,请参考以下文章

Linq-to-SQL 数据检索速度比较

Linq-to-SQL 和 DateTime 的怪异

如何改进 Linq-To-Sql 代码

Linq-to-SQL 数据库文件为空

Linq学习随笔三------LINQ to SQL

Linq to SQL 还是 Linq to DataSet?