COM Interop AccessViolationException间歇性地WCF回调

时间:2014-11-10 21:04:14

标签: c# wcf vb6 com-interop sta

我们有一个基于.NET 4的服务,它通过回调自托管WCF服务。我们将此服务封装在公开COM对象的.NET 4 dll中。这项服务被各种各样的客户使用,其中大多数是基于.NET的。

不幸的是我们有一些我们无法更改的VB6客户端,并且在调用某些回调方法时我们正在获取AccessViolationExceptions。

服务的结构方式是回调,如下所示。

MethodA 由VB6客户端调用,通过.NET dll代理到WCF服务(尚未返回)

WCF CallbackA 调用提供枚举状态值

可能会调用WCF CallbackB ,需要VB6客户端的进一步输入(此信息无法在MethodA的开头获得并影响MethodA的结果)

MethodA 返回

CallbackA (效果很好,没有异常!)它是一个提供Enum的OneWayOperation,VB应用程序当前正在将此值写入RichTextbox。

CallbackB (导致AccessViolationException)是一个提供对象的方法,并期望一个不同的对象返回两个基于值的属性。

我觉得这是尝试在与主线程不同的线程上创建COM对象的某种问题(因为它当前挂在MethodA上)。不幸的是我不知道如何纠正这个问题。我们可以控制服务中的代码,封装dll,我们可以建议VB6客户端中的代码。

我们有自己的VB6测试应用程序,我们可以绕过AccessViolation错误....但它涉及注释掉回调方法中的任何代码(参见下面的代码)我已经突出显示导致异常的行如果保留"< -----导致异常"。非常感谢任何帮助,如果您需要更多信息,请告诉我。

Private Function ITerminalCallbackComClient_VerifySignature() As Long
Dim result As Long

'Not-Authorized = 0 and Authorized = 1'
result = 0

Dim msgResponse As Long

msgResponse = MsgBox("Signature Accepted?", vbYesNo + vbQuestion, "Signature Verification")

If msgResponse = vbYes Then
    result = 1
End
End If

ITerminalCallbackComClient_VerifySignature = result
End Function

更新2014-11-13

回调在Visual Studio 6中调试时有效。但是,只要我们"制作"示例项目在执行回调时崩溃。如果我们删除对MsgBox的引用并仅映射回静态值,它将按预期工作。

我们已将Signature更新为COM Interop以删除所有对象引用,而不只是返回0或1以避免对象命名问题。

我已经更新了上面的VB6回调代码。

回调合约

[CallbackBehaviorAttribute(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public abstract class PS_Terminal_Link_Callback : ITerminalCallback
{

public abstract long VerifySignature();

}

服务合同

[ServiceContract(CallbackContract=typeof(ITerminalCallback))]
public interface ITerminal
{
   *MethodA*
}

2 个答案:

答案 0 :(得分:0)

如果是VB6代码,则LONG是VB6中的win32整数。对于16位基本整数的兼容性,VB6中为16位。多头是32位。您将VB6长(32位)放入消息框行中的VB6整数(16位)。

您的其他对象是私密的,因此我们无法查找其规格和文档。

答案 1 :(得分:0)

您也可以从调试器开始。

windbg或ntsd(ntsd是一个控制台程序,可能已安装)。两者都来自Windows调试工具。

下载并安装适用于Windows的调试工具

http://msdn.microsoft.com/en-us/windows/hardware/hh852363

安装Windows SDK,但只需选择调试工具。

在** C:**

中创建名为符号的文件夹

启动Windbg。 文件菜单 - 符号文件路径并输入

srv*C:\symbols*http://msdl.microsoft.com/download/symbols

然后

windbg -o -g -G c:\windows\system32\cmd.exe /k batfile.bat

您可以按F12停止它,kb将显示调用堆栈(g继续程序)。如果有错误,它也会停止并显示它们。

键入lm列出已加载的模块,x *!*列出符号,bp symbolname设置断点

如果在VB6中编程,则此环境变量link = / pdb:none将符号存储在dll中而不是单独的文件中。确保使用No Optimisations编译程序并勾选Create Symbolic Debug Info框。两者都在项目属性的“编译”选项卡上。

CoClassSyms(microsoft.com/msj/0399/hood/hood0399.aspx)也可以从类型库中创建符号。

在COM调用上放置一个断点(使用x *!*来查找它)。

现在您可以检查参数和/或查看详细的异常信息。