c# - 在 .NET WMQ API 中接收 WebSphere MQ 消息有时会抛出 MQRC_RFH_FORMAT_ERROR

标签 c# .net ibm-mq

我使用 WebSphere MQ v7 Server 和 WebSphere MQ Client v7.5 以及 amqmdnet.dll 7.5.0.0 作为 .NET 库通过 WebSphere MQ 进行通信。有时,当我尝试从队列中读取 MQMessage 时,我会收到 MQException,原因是 MQRC_RFH_FORMAT_ERROR

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

此行为似乎取决于消息的发送者及其内容。它通常不适用于不同平台上发送具有 float 或 double 属性的消息的系统。

最佳答案

这是 IBM 的 amqmdnet.dll 中的全局化错误。在客户端上打开 MQ 跟踪 (strmqtrc.exe) 后,我尝试再次接收消息,并在跟踪文件之一中发现了这一点:

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

使用.NET Reflector反编译MQMarshalMessageForGet显示了这个:

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

    switch (dt)
    {
        ...

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

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

        ...
    }

    ...
}

消息是在当前系统的文化中读取的,而不是在传输预期的文化中(在所有平台上应该是相同的)!重现问题的简单测试:

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

关于c# - 在 .NET WMQ API 中接收 WebSphere MQ 消息有时会抛出 MQRC_RFH_FORMAT_ERROR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11829264/

相关文章:

c# - 我的团队成员不支持在 ASP.NET Web 应用程序中使用 Crystal 报表

c# - 有没有办法让 WPF 应用程序尊重 Windows 10 中暗/亮主题的系统选择?

c# - 如果没有父节点,如何删除节点

jms - 无法在 WebSphere MQ 队列中看到 JMS 消息

java - 如何使用 IBM MQ 在字符串中添加带有(名称和值)的 header

c# - Mysql如果存在则更新否则插入

c# - 获取错误解析或读取时的整个 CSV 行

.net - 使用 [Obsolete] 属性来指示开发人员不要使用 API 的某些部分是一种好习惯吗?

c# - 使用 DigestMethod 的 sha256 算法修改 C# list

java - 什么是 JAVA8 的类型转换?