3

我的应用程序向 SAP 发送了大量数据。为此,它构建了一个 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, 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_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并没有改变任何东西。


更新:

即使我运行单个线程,似乎也会出现这个问题!这是怎么回事??

有没有办法禁用连接池以查看是否可以修复它?


更新:

@Igal Serban 的回答似乎对我有用。明天早上我会检查日志并(希望)奖励赏金!非常感谢。


更新:

根据要求,我的 librfc32.dll 版本是 6403.3.78.4732。

4

4 回答 4

1

更新 4:再想一想,我认为 librfc 版本并不重要。异常似乎来自托管代码。我能想到的选项是:

  • 尝试在单线程版本上使用调试器。
  • 神奇的方式。即使没有找到错误(那是在 sap 或您的代码上)。只要改变你做生意的方式就可以让它消失。它丑陋,但有时很实用。无论如何,您的场景推荐的方法似乎是使用连接池,而不是为每个请求创建新的代理对象。所以可以使用这样的(未经测试的)代码:

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)
}

此示例隐式使用连接池。可以从配置文件中控制使用。

更新 3:您能检查一下您的 librfc32.dll 版本和日期吗?它应该在 system32 目录或您的应用程序目录或您的 %path% 的某个位置。

更新 2: Sap 笔记就像 kb 文章。我不知道是否可以免费访问 sdn.sap.com 中的注释,所以我已将其发送到您的邮箱。

更新 1: SAP Note 1000057 指出:

在多线程重负载下,可能会出现引用 System.Xml.Xsl.XsltException 作为内部异常的 RfcMarshalException 类型的异常。

虽然不完全是您收到的异常。这值得一试。

补丁作为本说明的附件提供。

**更新0:**只是猜测。但我建议查看线程问题。这是所有的堆栈吗?您可以在调用 sap 代码的代码中发布部分吗?

于 2008-12-19T21:21:28.020 回答
1

编辑

我仍然认为这与映射有关。我相信 RFCTYPE_BCD 类型是十进制的(Business Connector Decimal),因此很难将日期值推入其中(有时可能会起作用?)。我建议重新生成代理,或在收到错误时记录正在编组的数据。像这样的东西(抱歉 - 我们使用自己的代理层,所以我对 Business Connector 不太熟悉):

您能否将以下内容翻译成 VB(以及任何 sapTable 结构的格式):

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

我知道这很痛苦,但只要在错误发生时快速而肮脏地获取一些数据以吐出。

========

仅从您发布的描述来看,我能想到的最好的可能是您正在尝试将日期值 (20081219) 编组到时间字段中?

您可以将该调用包装在 try/catch 中并记录发送到 SAP 的表的值并在此处发布吗?我希望数据中有线索。

通过向 SAP 发布 Web 服务,我知道 SAP 非常注重其日期时间和值的格式。

于 2009-03-06T04:38:04.593 回答
0

看起来它正在尝试将整数或字符串(由于 ToString() 无法分辨)转换为BCD(二进制编码的十进制)类型。

只是一个猜测,希望对你有帮助。

更新:

可能不会。

多个线程使用同一个连接?这可能不是一个好主意,除非您使用锁定,这将使线程毫无意义。我确定 SAP 支持连接池,所以在它自己的线程中打开连接(每个线程一个)。

于 2009-03-06T04:43:16.140 回答
0

可能是日期格式问题?你说它不会每次都发生。
因此,当您通过 20081202 时,它将“12”作为日部分,将 02 作为月部分。没关系。
但是,当您通过 20081219 时,它会尝试将 19 解析为一个月并抛出异常?
请咨询您的 SAP 管理员。

于 2009-03-06T18:21:46.593 回答