SAP .NET Connector: системное исключение, генерируемое при маршалинге типа .NET - PullRequest
3 голосов
/ 19 декабря 2008

Мое приложение отправляет много и много данных в 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 вместо этого ничего не изменило.


Обновление:

Кажется, эта проблема возникает, даже когда я запускаю один поток! В чем дело ??

Есть ли способ отключить пул соединений, чтобы посмотреть, исправляет ли это?


Обновление:

@ Ответ Игала Сербана, похоже, работает на меня. Завтра утром я проверю логи и (надеюсь) награжу щедростью! Большое спасибо.


Обновление:

По запросу моя версия librfc32.dll: 6403.3.78.4732.

Ответы [ 4 ]

1 голос
/ 06 марта 2009

Редактировать

Я все еще думаю, что это как-то связано с отображением. Я считаю, что тип 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, и опубликовать их здесь? Я надеюсь, что в данных есть ключ.

Из публикаций в Web-сервисе в SAP я знаю, что SAP довольно точно относится к формату даты и времени.

1 голос
/ 20 декабря 2008

Обновление 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-нота 1000057 заявляет:

При многопоточной большой нагрузке могут возникать исключения типа RfcMarshalException со ссылкой на System.Xml.Xsl.XsltException в качестве внутреннего исключения.

Пока вы не совсем исключение. Стоит попробовать.

Патч доступен как приложение к этой заметке.

** Обновление 0: ** Только предположение. Но я бы посоветовал взглянуть на проблемы с потоками. Это весь стек? Можете ли вы разместить часть кода, где вы называете код SAP?

0 голосов
/ 06 марта 2009

Может ли это быть проблема формата даты? Вы говорите, что это происходит не каждый раз.
Таким образом, когда вы проходите 20081202, он принимает '12' как часть дня и 02 как часть месяца. Все в порядке.
Но когда вы проходите 20081219, он пытается проанализировать 19 как месяц и выдает исключение?
Обратитесь к администратору SAP.

0 голосов
/ 06 марта 2009

Похоже, что он пытается преобразовать целое число или строку (не могу сказать из-за ToString ()) в тип BCD (двоично-десятичный код).

Просто предположение, надеюсь, это поможет.

ОБНОВЛЕНИЕ:

Не угадай.

Несколько потоков, использующих одно и то же соединение? Это, вероятно, не очень хорошая идея, если вы не используете блокировку, которая сделает поток бессмысленным. Я уверен, что SAP поддерживает пулы соединений, поэтому откройте соединение в своем собственном потоке (по одному на поток).

...