简体   繁体   中英

Reading/Writing a websphere queue from an Async method

I have a asynchronous method that is responsible for only connecting to the queue and reading from the queue. While trying to read I get an error from the WebSphere dll 'amqmdnet.dll' that says "Thread was being aborted". I get this error every time I try to modify the queue in any way, and only when I try to modify from an asynchronous method. I've also tried implementing the IBM.XMS.net dll as this was said to be used for asynchronous messaging, although I get the same error. Is it possible to read a queue from inside an async method? If so, is the implementation for reading/writing different for synchronous and asynchronous when it comes to modifying the queue itself? I can connect to the queue manager just fine, its modifying the queue that's giving me issues.

Main:

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

I think there is some confusion here between Asynchronous messaging pattern of IBM MQ and Asynchronous programming concept of .NET Framework.

IBM MQ enables application to application connectivity in an asynchronous way through queuing. In a typical client-server pattern, both client and server applications need to be up and running always for data exchange. This is synchronous pattern. In asynchronous pattern, client application and server application are not required to be running always. Client can send a message to MQ and go away. The message will be residing in a MQ queue. If the server application is running, that message will be delivered to server application. The server will process that message and put a reply message into MQ queue and go away. The client application can come back after some time and read the reply message. As you can see client and server applications are not simultaneously but still they are able to communicate in a asynchronous way via MQ.

I am not an expert in the newer .NET Framework concepts. The async programming concept in .NET Framework is for offloading short tasks that can be independently by the CPU without blocking a thread. For example when the main thread is busy displaying contents of a web page, the job of connecting to a database could be offloaded to a .NET task so that the user is able to interact with the web page.

IBM MQ .NET (amqmdnet and XMS) use multiple threads for communicating with a queue manager. I am unsure if 'async' programming technique is suitable when multiple threads are involved. This could be the reason for "Thread was being aborted" error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM