【问题标题】:Reading/Writing a websphere queue from an Async method从异步方法读取/写入 websphere 队列
【发布时间】:2016-02-10 09:01:13
【问题描述】:

我有一个异步方法,它只负责连接到队列并从队列中读取。在尝试读取时,我从 WebSphere dll 'amqmdnet.dll' 中得到一个错误,上面写着“线程被中止”。每次我尝试以任何方式修改队列时都会出现此错误,并且仅当我尝试从异步方法进行修改时。我也尝试过实现 IBM.XMS.net dll,因为据说它用于异步消息传递,尽管我得到了同样的错误。是否可以从异步方法中读取队列?如果是这样,在修改队列本身时,同步和异步的读/写实现是否不同?我可以很好地连接到队列管理器,它修改了给我带来问题的队列。

主要:

private async Task ReadAsync()
{
   await MqMessanger.ConnectAsync(); // connects fine
   await MqMessanger.StartReadingAsync(); // errors out
}

MqMessanger:(IBM.XMS.net dll)

private XMSFactoryFactory factoryFactory; //used for connection
private IConnectionFactory cf; //used for connection
private ISession sessionWMQ;
private IDestination destination;
private IMessageConsumer consumerAsync;
private MessageListener messageListener;
public IConnection QueueManager { get; set; }

//QueueManager has been connected prior to this
private void StartReadingAsync()
{
    try
    {
        //Creates a session where an Ack is sent to the server to delete the message as soon the message is received. 
        sessionWMQ = QueueManager.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
        destination = sessionWMQ.CreateQueue(queueName);

        // Create consumer object to read messages from the queue
        consumerAsync = sessionWMQ.CreateConsumer(destination);

        // Create a message listener to fire when a message is put on the queue and assign it to consumer
        messageListener = new MessageListener(OnMessageCallback);
        consumerAsync.MessageListener = messageListener;                    
    }
    catch (Exception ex)
    {
        throw new Exception($"Error reading from '{destination.Name}'.", ex);
    }
}

MqMessanger: (amqmdnet dll)

//QueueManager has been connected prior to this
private void StartReadingAsync()
{
    try
    {
       queue = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
        queueMessage = new MQMessage();
        queueMessage.Format = MQC.MQFMT_STRING;
        queueGetMessageOptions = new MQGetMessageOptions();
        queue.Get(queueMessage, queueGetMessageOptions);
        string message = queueMessage.ReadString(queueMessage.MessageLength);
        //Do something with this message
    }
    catch (Exception ex)
    {
       throw new Exception($"Error reading from '{destination.Name}'.", ex);
    }

【问题讨论】:

    标签: c# asynchronous ibm-mq


    【解决方案1】:

    我认为 IBM MQ 的异步消息传递模式和 .NET Framework 的异步编程概念之间存在一些混淆。

    IBM MQ 通过队列以异步方式启用应用程序到应用程序的连接。在典型的客户端-服务器模式中,客户端和服务器应用程序都需要始终启动并运行以进行数据交换。这是同步模式。在异步模式中,客户端应用程序和服务器应用程序不需要始终运行。客户端可以向 MQ 发送消息并离开。消息将驻留在 MQ 队列中。如果服务器应用程序正在运行,则该消息将被传递到服务器应用程序。服务器将处理该消息并将回复消息放入 MQ 队列并离开。客户端应用程序可以在一段时间后返回并阅读回复消息。如您所见,客户端和服务器应用程序不是同时进行的,但它们仍然能够通过 MQ 以异步方式进行通信。

    我不是较新的 .NET Framework 概念方面的专家。 .NET Framework 中的async 编程概念用于卸载可由 CPU 独立执行且不会阻塞线程的短任务。例如,当主线程忙于显示网页的内容时,可以将连接到数据库的工作卸载到 .NET 任务中,以便用户能够与网页进行交互。

    IBM MQ .NET(amqmdnet 和 XMS)使用多个线程与队列管理器进行通信。当涉及多个线程时,我不确定“异步”编程技术是否适用。这可能是“线程被中止”错误的原因。

    【讨论】:

    • async/await 模式提供了对异步代码(如网络 I/O)的抽象,因此 Task 类非常适合 IBM MQ。不幸的是,amqmdnet 似乎不支持?每个Put()Get() 方法都返回void 而不是Task,所以它都是Sync-over-Async 代码,这是一种反模式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2016-04-14
    • 1970-01-01
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多