Interface SAP.NET连接器:封送.NET类型时引发系统异常
我的应用程序向SAP发送大量数据。要对此进行di,它将构建一个SAP表对象并将其发送过来。我经常会遇到这种错误,但不可靠:Interface SAP.NET连接器:封送.NET类型时引发系统异常,interface,marshalling,sap,saprfc,sap-dotnet-connector,Interface,Marshalling,Sap,Saprfc,Sap Dotnet Connector,我的应用程序向SAP发送大量数据。要对此进行di,它将构建一个SAP表对象并将其发送过来。我经常会遇到这种错误,但不可靠: System exception thrown while marshaling .NET type 20081219 to RFCTYPE_BCD at SAP.Connector.Rfc.RfcMarshal.NetFieldToRfcField(Object src, RFCTYPE type, Encoding encoding, Byte[] dest, I
System exception thrown while marshaling .NET type 20081219 to RFCTYPE_BCD
at SAP.Connector.Rfc.RfcMarshal.NetFieldToRfcField(Object src, RFCTYPE type, Encoding encoding, Byte[] dest, Int32 offset, Int32 len, Int32 charSize, Int32 decimals)
at SAP.Connector.Rfc.RfcStructureUtil.ToRfcStructure(Object obj, Byte[] dest, Type t, Encoding encoding, Boolean isUnicode, PropertyInfo[] propinfos, RfcStructInfo structInfo)
at SAP.Connector.Rfc.RfcStructureUtil.GetITabFromList(SAPConnection conn, Object list, Type t, RfcStructInfo structInfo, Int32 itab)
at SAP.Connector.Rfc.RfcClient.PrepareClientParameters(Type classType, MethodInfo m, Boolean isTQRfc, Object[] MethodParamsIn, RFC_PARAMETER[]& paramsIn, RFC_PARAMETER[]& paramsOut, RFC_TABLE[]& tables, ParameterMap[]& paramMaps)
at SAP.Connector.Rfc.RfcClient.RfcInvoke(SAPClient proxy, String method, Object[] methodParamsIn)
at SAP.Connector.SAPClient.SAPInvoke(String method, Object[] methodParamsIn)
奇怪的是,这并不是每次都会发生。另外,它抱怨的.NET类型“20081219”是我传递的数据(日期)——而不是类型。我认为该字段的类型是RFCTYPE.RFCTYPE\u TIME
对如何排除此间歇性错误有何建议?在调用SAP RFC之间是否有某种状态需要清除
更新: 根据要求,以下是调用SAP的代码:
Using sapConnection As New MySapProxy(ConnectionString)
sapConnection.Connection.Open()
sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
End Using
我在想也许多个线程正在使用相同的连接。改用SAP.Connector.GetNewConnection
并没有改变任何东西
更新: 看起来这个问题甚至在我运行单个线程时也会发生!怎么回事 有没有办法禁用连接池,看看是否可以修复它
更新: @伊格尔·塞班的回答似乎对我有用。明天早上我会检查日志,(希望)奖励赏金!非常感谢
更新:
根据要求,我的librfc32.dll版本是6403.3.78.4732。更新4:仔细想想,我认为librfc版本并不重要。例外情况似乎来自托管代码。我能想到的选择是:
- 尝试在单线程版本上使用调试器
- 神奇的方式。即使没有找到bug(在sap或您的代码上)。仅仅改变你做生意的方式就能让它消失。这很难看,但有时很实用。无论如何,对于您的场景,推荐的方法似乎是使用连接池,而不是为每个请求创建新的代理对象。因此,可以使用类似以下(未经测试的)代码:
此示例隐式使用连接池。可以从配置文件控制的使用 更新3:您能检查一下您的librfc32.dll版本和日期吗?它应该位于system32目录、应用程序目录或%path%中的某个位置 更新2:Sap笔记就像kb文章一样。我不知道sdn.sap.com上是否有免费访问该便笺的权限,因此我已将其发送到您的邮件中 更新1:SAP注释1000057说明: 在多线程重载下,可能会发生RFCMarshaleException类型的异常,并将System.Xml.Xsl.XsltException作为内部异常引用 而不完全是你收到的例外。值得一试 修补程序作为本说明的附件提供 **更新0:*只是猜测。但我建议您看看线程问题。这就是全部的堆栈吗?您可以将代码中的部分发布到调用sap代码的位置吗?编辑: 我仍然认为这与地图有关。我相信RFCTYPE_BCD类型是decimal(businessconnector decimal),因此它将很难将日期值推入其中(有时可能会工作?)。我建议重新生成代理,或者在出现错误时记录正在封送的数据。类似这样(抱歉,我们使用自己的代理层,所以我对Business Connector不太熟悉): 能否将以下内容翻译成VB(以及sapTable结构的任何格式): 我知道这很痛苦,但是只要做一个快速而肮脏的操作,当错误发生时,就可以得到一些数据 ======== 从您发布的描述来看,我能想到的最好的方法可能是您正在尝试将日期值(20081219)封送到时间字段中 您能否将该调用包装在try/catch中,并记录发送到SAP的表的值,然后将这些值发布到此处?我希望数据中有线索 通过向SAP发布web服务,我知道SAP对其日期时间和值的格式非常挑剔。看起来它正在尝试将整数或字符串(由于ToString()无法判断)转换为(二进制编码的十进制)类型 只是一个猜测,希望有帮助 更新: 我想不是
使用相同连接的多个线程?这可能不是一个好主意,除非您使用锁定,这将使线程毫无意义。我确信SAP支持连接池,所以在它自己的线程中打开连接(每个线程一个)。可能是日期格式问题吗?你说它不是每次都发生。
因此,当你通过20081202,它需要'12'作为一天的一部分和02作为一个月的一部分。没关系。
但当您通过20081219时,它会尝试将19解析为一个月,并抛出异常?
请与您的SAP管理员联系。既然您提到了它,那就很有意义了。我将强制应用程序运行到一个线程,看看问题是否消失。当运行一个线程时,问题确实消失了。现在我只想弄明白为什么…@Igal Serban:不幸的是,这并没有解决问题。不过,我认为您的思路是正确的--它似乎是突然出现的,可能是在高负载时间。根据要求,我的librfc32.dll版本是6403.3.78.4732。我同意通过保持长期连接来减少连接周期可能会有所帮助,但这会很好,要知道真正的问题是什么。不幸的是,我排除了格式问题,因为这种情况并不总是发生。不,每个线程都有自己的连接。事实上,我更改了它,这样每个线程都可以在每次需要时创建和打开/关闭连接。这没有帮助。不幸的是,我排除了格式问题,因为这种情况并没有持续发生。也就是说,它使用相同的数据工作和失败。
MySapProxy proxy = new MySapProxy(); // do this only once.
// and in you main loop:
using (proxy.Connection = Connection.GetConnection(connectionString))
{
proxy.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
}
Using sapConnection As New MySapProxy(ConnectionString)
sapConnection.Connection.Open()
try {
sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
} catch (Exception e) {
StringBuilder sb = new StringBuilder();
foreach (Field f in sapTable.Fields) {
sb.AppendLine(f.Name + "=" f.Value);
}
sb.AppendLine(e.StackTrace);
File.AppendAllText("C:\\Exception_" + DateTime.Now.ToString("u") + ".txt", sb.ToString());
}
End Using