2012-08-06 2 views
2

WebSphere MQ를 통해 통신하기 위해 .NET 라이브러리로 amqmdnet.dll 7.5.0.0과 함께 WebSphere MQ v7 Server 및 WebSphere MQ Client v7.5를 사용하고 있습니다. 때때로 큐에서 MQMessage을 읽으려고하면 MQExceptionMQRC_RFH_FORMAT_ERROR이 표시됩니다..NET WMQ API에서 WebSphere MQ 메시지를 수신하면 때때로 MQRC_RFH_FORMAT_ERROR가 발생합니다.

var message = new MQMessage(); 
queue.Get(message); 

이 동작은 메시지를 보낸 사람과 그 내용에 따라 다르게 보입니다. 일반적으로 다른 플랫폼에서 float 또는 double 속성을 사용하여 메시지를 보내는 시스템에서는 작동하지 않습니다.

답변

3

이것은 IBM의 amqmdnet.dll에있는 세계화 버그입니다. 클라이언트 (strmqtrc.exe)에 MQ 추적을 켠 후 다시는 메시지를 받기 위해 노력하고 내가 추적 파일 중 하나에서 이걸 발견 :

private object GetValueAsObject(string dt, string propValue) 
{ 
    ... 

    switch (dt) 
    { 
     ... 

     case "r4": 
      return Convert.ToSingle(propValue); 

     case "r8": 
      return Convert.ToDouble(propValue); 

     ... 
    } 

    ... 
} 

메시지 :

00001F21 11:48:00.351013 7104.1   :  Exception received 
System.FormatException 
Message: Input string was not in a correct format. 
StackTrace: 
    at System.Number.ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt) 
    at System.Convert.ToSingle(String value) 
    at IBM.WMQ.MQMarshalMessageForGet.GetValueAsObject(String dt, String propValue) 
    at IBM.WMQ.MQMarshalMessageForGet.ProcessAllAvailableRFHs() 
00001F22 11:48:00.351115 7104.1   :  We are not sucessful in parsing one of theRFH2Header.Raise the RFH_FORMAT exception and breakfurther processing in loop 
00001F23 11:48:00.351825 7104.1   :  MQException CompCode: 2 Reason: 2421 

디 컴파일 MQMarshalMessageForGet.NET Reflector 이것을 보여 주었다 (모든 플랫폼에서 동일해야합니다) 운송 문화에 있지 않은 현재 시스템의 문화에서 읽혀집니다! 나는이 간단한 범위 클래스를 사용하고

[Test] 
public void PutAndGetMessageWithFloatProperty() { 
    using (MQQueue queue = _queueManager.AccessQueue(TestQueue, MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF)) 
    { 
     Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); 

     MQMessage message = new MQMessage(); 
     message.SetFloatProperty("TEST_SINGLE", 14.879f); 
     message.WriteString("some string"); 
     message.Format = MQC.MQFMT_STRING; 

     queue.Put(message); // Writes property value as 14.879 

     Thread.CurrentThread.CurrentCulture = new CultureInfo("cs-CZ"); 

     MQMessage readMessage = new MQMessage(); 
     queue.Get(readMessage); // Throws MQException because 14,879 is correct format 

     queue.Close(); 
    } 
} 

해결 방법 : : 간단한 테스트는 문제를 재현하는

public class CultureForThreadScope : IDisposable { 
    private readonly CultureInfo oldCulture; 

    public CultureForThreadScope(CultureInfo culture) { 
     oldCulture = Thread.CurrentThread.CurrentCulture; 
     Thread.CurrentThread.CurrentCulture = culture; 
    } 

    public void Dispose() { 
     Thread.CurrentThread.CurrentCulture = oldCulture; 
    } 
} 

그리고 범위에 대한 모든 Get 전화를 포장하고있다.

using (new CultureForThreadScope(CultureInfo.InvariantCulture)) { 
    destination.Get(message, getOptions); 
}