hur*_*uda 6 dll biztalk unmanaged appdomain c#-4.0
我已经看过许多关于异常的帖子"无法通过AppDomains传递GCHandle",但我仍然没有得到它......
我正在使用由DLL驱动的RFID阅读器.我没有此DLL的源代码,只有一个示例来说明如何使用它.
该示例工作得很好,但我必须在另一个项目中复制一些代码,以将读取器添加到中间件Microsoft Biztalk.
问题是Microsoft Biztalk的进程在另一个AppDomain中工作.阅读器在读取标签时处理事件.但是当我在Microsoft Biztalk下运行它时,我遇到了这个令人烦恼的异常.
我看不出任何有关如何使其工作的解决方案......
以下是一些可能有趣的代码:
// Let's connecting the result handlers.
// The reader calls a command-specific result handler if a command is done and the answer is ready to send.
// So let's tell the reader which functions should be called if a result is ready to send.
// result handler for reading EPCs synchronous
Reader.KSRWSetResultHandlerSyncGetEPCs(ResultHandlerSyncGetEPCs);
[...]
var readerErrorCode = Reader.KSRWSyncGetEPCs();
if (readerErrorCode == tKSRWReaderErrorCode.KSRW_REC_NoError)
{
// No error occurs while sending the command to the reader. Let's wait until the result handler was called.
if (ResultHandlerEvent.WaitOne(TimeSpan.FromSeconds(10)))
{
// The reader's work is done and the result handler was called. Let's check the result flag to make sure everything is ok.
if (_readerResultFlag == tKSRWResultFlag.KSRW_RF_NoError)
{
// The command was successfully processed by the reader.
// We'll display the result in the result handler.
}
else
{
// The command can't be proccessed by the reader. To know why check the result flag.
logger.error("Command \"KSRWSyncGetEPCs\" returns with error {0}", _readerResultFlag);
}
}
else
{
// We're getting no answer from the reader within 10 seconds.
logger.error("Command \"KSRWSyncGetEPCs\" timed out");
}
}
[...]
private static void ResultHandlerSyncGetEPCs(object sender, tKSRWResultFlag resultFlag, tKSRWExtendedResultFlag extendedResultFlag, tKSRWEPCListEntry[] epcList)
{
if (Reader == sender)
{
// Let's store the result flag in a global variable to get access from everywhere.
_readerResultFlag = resultFlag;
// Display all available epcs in the antenna field.
Console.ForegroundColor = ConsoleColor.White;
foreach (var resultListEntry in epcList)
{
handleTagEvent(resultListEntry);
}
// Let's set the event so that the calling process knows the command was processed by reader and the result is ready to get processed.
ResultHandlerEvent.Set();
}
}
Run Code Online (Sandbox Code Playgroud)
您的gcroot<> 辅助类有问题。它用在没人能看到的 DLL 内部的代码中。它经常被旨在与托管代码互操作的 C++ 代码使用,gcroot<> 存储对托管对象的引用。该类使用 GCHandle 类型来添加引用。GCHandle.ToIntPtr() 方法返回 C++ 代码可以存储的指针。失败的操作是 GCHandle.FromIntPtr(),C++ 代码使用它来恢复对对象的引用。
获得此异常有两种基本解释:
它可以是准确的。当您从一个 AppDomain 初始化 DLL 中的代码并在另一个 AppDomain 中使用它时,就会发生这种情况。从代码片段中并不清楚 Reader 类对象是在哪里初始化的,因此这就是解释的可能性非零。请确保使其靠近使用 Reader 类的代码。
它可能是由 DLL 内的 C++ 代码中存在的另一个错误引起的。非托管代码经常遭受指针错误,这种错误可能会意外覆盖内存。如果存储 gcroot<> 对象的字段发生这种情况,那么一段时间内不会出现任何问题。直到代码再次尝试恢复对象引用。此时,CLR 注意到损坏的指针值不再与实际对象句柄匹配,并生成此异常。这无疑是一种很难解决的错误,因为这种情况发生在您无法修复的代码中,并且向处理该错误的程序员展示该错误的重现非常困难,此类内存损坏问题永远不会很好地重现。
首先追击#1 子弹。Biztalk 在单独的 AppDomain 中运行 C# 代码的可能性很大。并且 DLL 在创建 AppDomain 之前或同时加载得太快。您可以通过 SysInternals 的 ProcMon 看到一些内容。通过编写一个创建 AppDomain 并运行测试代码的小测试程序来创建此过程的重现。如果崩溃重现,那么您将有一个很好的方法向 RFID 供应商展示该问题,并且有些人希望他们会使用它并进行修复。
与 RFID 读取器供应商建立良好的合作关系以达成解决方案非常重要。这从来都不是问题,总是一个去其他地方购物的好理由。
| 归档时间: |
|
| 查看次数: |
825 次 |
| 最近记录: |