2015-07-11 114 views
4

我試圖從websphere mq隊列讀取消息並將其轉儲到另一個隊列中。在for循環中啓動多個線程不起作用

下面是代碼我必須這樣做

private void transferMessages() 
{ 
    MQQueueManager sqmgr = connectToQueueManager(S_SERVER_NAME, S_QMGR_NAME, S_PORT_NUMBER, S_CHANNEL_NAME); 
    MQQueueManager dqmgr = connectToQueueManager(D_SERVER_NAME, D_QMGR_NAME, D_PORT_NUMBER, D_CHANNEL_NAME); 
    if (sqmgr != null && dqmgr != null) 
    { 
     MQQueue sq = openSourceQueueToGet(sqmgr, S_QUEUE_NAME); 
     MQQueue dq = openDestQueueToPut(dqmgr, D_QUEUE_NAME); 
     if (sq != null && dq != null) 
     { 
      setPutMessageOptions(); 
      setGetMessageOptions(); 
      processMessages(sqmgr, sq, dqmgr, dq); 
     } 
    } 
} 

我打電話的for循環上述方法和下面創建單獨的線程。

int NO_OF_THREADS = 5; 
Thread[] ts = new Thread[NO_OF_THREADS]; 
for (int i = 0; i < NO_OF_THREADS; i++) 
{ 
    ts[i] = new Thread(() => transferMessages()); 
    ts[i].Start();   
} 

正如您所看到的,我正在與transferMessages方法中的隊列管理器建立新的連接。由於某些原因不確定,程序只與MQ建立一個連接。

自定義的方法來連接到隊列管理器低於..

private MQQueueManager connectToQueueManager(string MQServerName, string MQQueueManagerName, string MQPortNumber, string MQChannel) 
    { 
     try 
     { 
      mqErrorString = ""; 
      MQQueueManager qmgr; 
      Hashtable mqProps = new Hashtable(); 
      mqProps.Add(MQC.HOST_NAME_PROPERTY, MQServerName); 
      mqProps.Add(MQC.CHANNEL_PROPERTY, MQChannel); 
      mqProps.Add(MQC.PORT_PROPERTY, Convert.ToInt32(MQPortNumber)); 
      mqProps.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT); 
      qmgr = new MQQueueManager(MQQueueManagerName, mqProps); 
      return qmgr; 
     } 
     catch (MQException mqex) 
     { 
      //catch and log MQException here 
      return null; 
     } 
    } 

任何建議我失去了什麼?

+1

鏈中的某些內容正在序列化連接調用。無論是在你自己的connectToQueueManager還是在MQ API中。反正你不應該使用線程(看看任務和線程池)。 –

+0

@亨克,我已經添加了自定義的connectToQueueManager方法代碼。除了通過HashTable存儲連接屬性來創建與隊列管理器的連接,並且使用標準MQ API與MQ隊列管理器建立連接之外,它沒有什麼比這更簡單。另外,根據您的建議,我將檢查任務或ThreadPools ..我會更新,一旦我找到我面臨的問題的修復。謝謝。 –

+0

如果您的應用程序連接了同一組隊列管理器,那麼爲什麼不連接並僅打開一次隊列! – Shashi

回答

1

這是因爲Shared Conversation(SHARECNV) MQ的特性,其中來自一個應用程序的隊列管理器的多個連接共享相同的套接字。此值是建立連接時在客戶端和隊列管理器之間協商的值。默認情況下,10個連接將通過套接字共享。

您可以將應用程序中的線程數增加到11,然後您可以看到正在打開的第二個連接。有關SHARECNV的更多詳情,請致電here

UPDATE 每次運行6個線程進行放置和獲取時的信道狀態。注意我連接到同一個隊列管理器(僅用於測試目的)。 SHARECNV設置爲10.

 2 : dis chstatus(MY.SVRCONN) 
AMQ8417: Display Channel Status details. 
    CHANNEL(MY.SVRCONN)      CHLTYPE(SVRCONN) 
    CONNAME(127.0.0.1)      CURRENT 
    STATUS(RUNNING)       SUBSTATE(RECEIVE) 
AMQ8417: Display Channel Status details. 
    CHANNEL(MY.SVRCONN)      CHLTYPE(SVRCONN) 
    CONNAME(127.0.0.1)      CURRENT 
    STATUS(RUNNING)       SUBSTATE(RECEIVE) 

當每個運行5個線程時。

3 : dis chstatus(MY.SVRCONN) 
AMQ8417: Display Channel Status details. 
    CHANNEL(MY.SVRCONN)      CHLTYPE(SVRCONN) 
    CONNAME(127.0.0.1)      CURRENT 
    STATUS(RUNNING)       SUBSTATE(RECEIVE) 
+0

在發佈我的問題之前,我試着將其更改爲0和其他不同的值。沒有運氣。 –

+0

運行測試程序並將結果發佈爲UPDATE。 – Shashi

+0

您可以在啓動程序之前和之後發佈隊列管理器連接嗎? (DIS QMSTATUS CONNS)以及隊列IPPROCS和OPPROCS? 你是說上面的代碼有效,我必須在MQ configs/queue manager configs中做一些更改嗎? PS:我運行了另一個成功與隊列管理器建立多個連接的程序。當我現在運行它時,它失敗了。嘗試與其他隊列管理器進行測試。謝謝。 –