이것은 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);
}