就在最近,我的应用程序一直不一致地抛出各种异常,例如:
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Diagnostics.Process' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Drawing.SolidBrush' to type 'System.Transactions.SafeIUnknown'.
Unable to cast object of type 'System.Threading.Thread' to type 'System.Xml.Linq.XNamespace'.
(最后一个可能是其他的次要效果)
其中一些的堆栈跟踪粘贴在下面,但请注意,它们都具有以下 3 个最后步骤:
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
观察 - 这些例外:
- 经常发生,但不是一直发生(50%?)
- 当确实发生时不要总是产生相同的异常
- 与我的应用程序中导致它们的代码没有明显的联系
- 可在各种 PC 上重现
- 在我所做的任何搜索中都无法准确找到
该应用程序是一组通过 COM 从旧 VB6 代码调用的 C# DLL。然而,这已经存在多年,我们最近没有改变任何关于如何完成的事情。
它不是一个多线程的应用程序,所以涉及的演员表System.Threading.Thread
似乎不合适。有一个第三方模块使用了线程,但我们把它作为实验拿出来:这样做并没有解决问题,但似乎减少了错误的频率。这使我认为这是某种资源破坏问题。
我正在寻找建议,例如:
如果您以前确实见过这种异常模式,那么原因是什么?
关于如何调试根本问题的建议
示例堆栈跟踪:
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.SQLite.SQLiteConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
和
Unable to cast object of type 'System.Threading.Thread' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.Common.ADP.IsSysTxEqualSysEsTransaction()
at System.Data.Common.ADP.NeedManualEnlistment()
at System.Data.OleDb.OleDbConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
和
System.InvalidCastException: Unable to cast object of type 'System.Drawing.SolidBrush' to type 'System.Transactions.SafeIUnknown'.
at System.Transactions.Transaction.JitSafeGetContextTransaction(ContextData contextData)
at System.Transactions.Transaction.FastGetTransaction(TransactionScope currentScope, ContextData contextData, Transaction& contextTransaction)
at System.Transactions.Transaction.get_Current()
at System.Data.Common.ADP.IsSysTxEqualSysEsTransaction()
at System.Data.Common.ADP.NeedManualEnlistment()
at System.Data.OleDb.OleDbConnection.Open()
at Company.ABC.WrappedDbConnection.Open()
at Company.ABC.Program.DoSomething()
编辑:
我尝试使用 windbg(使用托管代码的 SOS 扩展)对此进行调查。
它能够打破异常。这是从那时起的堆栈跟踪:
0:000> !DumpStack
OS Thread Id: 0x2d44 (0)
Current frame: KERNELBASE!RaiseException+0x62
ChildEBP RetAddr Caller, Callee
0019b658 750325f2 KERNELBASE!RaiseException+0x62, calling ntdll!RtlRaiseException
0019b688 774a7310 ntdll!RtlFreeHeap+0x1e0, calling ntdll!RtlFreeHeap+0x560
0019b69c 70a9f09f clr+0xf09f, calling KERNEL32!TlsGetValue
0019b6ac 70b928f1 clr!GetMetaDataPublicInterfaceFromInternal+0x9741, calling KERNELBASE!RaiseException
0019b6ec 70aae56d clr!LogHelp_NoGuiOnAssert+0x2add, calling clr!LogHelp_NoGuiOnAssert+0x2a92
0019b6f8 70aae50f clr!LogHelp_NoGuiOnAssert+0x2a7f
0019b748 70bfc1a2 clr!CreateApplicationContext+0x1c2d2, calling clr!GetMetaDataPublicInterfaceFromInternal+0x95b6
0019b77c 70e3d369 clr!CreateHistoryReader+0x72069, calling clr!CreateApplicationContext+0x1c279
0019b7dc 70bc6a59 clr!PreBindAssemblyEx+0x10959, calling clr+0xf7b0
0019b80c 09364844 (MethodDesc 08e0d5b4 +0x4c System.Transactions.Transaction.JitSafeGetContextTransaction(System.Transactions.ContextData)), calling clr!LogHelp_TerminateOnAssert+0x7f00
0019b83c 09362f2f (MethodDesc 08e0d5e4 +0x9f System.Transactions.Transaction.FastGetTransaction(System.Transactions.TransactionScope, System.Transactions.ContextData, System.Transactions.Transaction ByRef)), calling (MethodDesc 08e0d5b4 +0 System.Transactions.Transaction.JitSafeGetContextTransaction(System.Transactions.ContextData))
0019b850 09362510 (MethodDesc 08e0d5fc +0x78 System.Transactions.Transaction.get_Current()), calling (MethodDesc 08e0d5e4 +0 System.Transactions.Transaction.FastGetTransaction(System.Transactions.TransactionScope, System.Transactions.ContextData, System.Transactions.Transaction ByRef))
0019b86c 08ddf67a (MethodDesc 08e04c6c +0x14b2 System.Data.SQLite.SQLiteConnection.Open()), calling (MethodDesc 08e0d5fc +0 System.Transactions.Transaction.get_Current())
0019ba70 08ddd8ea (MethodDesc 08e058b0 +0x22 Company.ABC.WrappedDbConnection.Open()), calling 0dfce43a
这与上面的 CLR 异常堆栈同步。
我主要想确定的是是否存在堆“腐败”。但显然不是:
0:000> !VerifyHeap
No heap corruption detected.
所以我认为这排除了我们的任何本机代码(或第 3 方)只会造成严重破坏。但是仍然没有真正理解这个问题。在我看来,它更像是数据库层中的一个错误。
这已在此处作为问题提交:https ://developercommunity2.visualstudio.com/t/Unable-to-cast-object-of-type-varies/1241378