2014-10-20 102 views
0

我有一個叫做消息傳遞的類。當一個類的實例被創建時,一個連接被建立到一個服務上,該服務又可以訪問一個數據庫。此連接需要5秒鐘(下面的Messaging.Connection MESConnection = new Messaging.Connection();)。該類有一種方法,用戶可以提交將數據放入數據庫的消息。避免長連接時間

當用戶按下按鈕時,我想使用線程向數據庫提交X條消息。我有使用任務parralel庫的工作,但問題是X線程創建類的X實例,這意味着如果X爲30例如整個操作大約需要10秒。

我怎麼能離線說有10個連接打開,這樣當提交消息時,與數據庫的連接已經打開,因此我可以避免5秒的連接時間?

C#代碼

// Loop through and multithread 


foreach (string container in containers) 
     { 

      int output = Convert.ToInt32(container); 
      Task t = Task.Factory.StartNew(() => 
      { 

       Messaging.Connection MESConnection = new Messaging.Connection(); //Takes 5 seconds 
       BSCContainerWorkflowResponse.BscContainerWorkflowResponse WorkflowResponse2; 

       // Get device next step 
       MESConnection.xmlMessage = Messaging.BscContainerNextTaskRequest(Convert.ToString(output)); 

       // Send message to MES 
       String result; 

       result = MESConnection.SendMessage(); 
       if (result != "") 
       { 
        MessageBox.Show("Error sending message to MES: " + result); 
        return null; 
       } 

       result = MESConnection.GetReply(); 
       if (result != "") 
       { 
        MessageBox.Show("Error receiving message from MES: " + result); 
        return null; 
       } 


       WorkflowResponse2 = BSCContainerWorkflowResponse.ReadBscContainerWorkflowResponse(MESConnection.xmlReply); 


       if (WorkflowResponse2.mes_message.msg_header.msg_stat < 0) 
       { 
        MessageBox.Show("Error with mes Response " + " message stat:" + Convert.ToString(WorkflowResponse.mes_message.msg_header.msg_stat) + " Error source " + (WorkflowResponse.mes_message.msg_error.error_source) + " Error code " + (WorkflowResponse.mes_message.msg_error.error_code) + " Error string " + Convert.ToString(WorkflowResponse.mes_message.msg_error.error_string), "MES Message Error"); 
        return null; 
       } 

       return WorkflowResponse2; 

      }).ContinueWith(o => 
      { 
       listBox1.Items.Add(o.Result.mes_message.msg_body.Container.Name + " " + o.Result.mes_message.msg_body.Container.Product.Name + " " + o.Result.mes_message.msg_body.Container.Product.BscModelNumber + " " + o.Result.mes_message.msg_body.Container.BscSerialNumber + " " + o.Result.mes_message.msg_body.Container.TaskList.Name + " " + o.Result.mes_message.msg_body.Container.TaskList.Revision + " " + Convert.ToString(o.Result.mes_message.msg_body.Container.MfgOrder.BscSWR)); 
       buttonSendBSCNextTaskRequestThreaded.Text = "Process"; 
       buttonSendBSCNextTaskRequestThreaded.Enabled = true; 

      }, TaskScheduler.FromCurrentSynchronizationContext()); 

     }  

回答

2

正確的方法是使用一個connection pool緩解長連接時間。 ADO.NET提供程序內置此功能。如果您的連接類沒有,您可以implement one yourself,因爲它可以提高整個應用程序的性能。

雖然,在這個特殊情況的正確方法是比較有什麼需要更長的時間:

  • 要建立多個連接通過
  • 重用,推動單一數據連接來推送數據通過

這將取決於您要通過的數據量以及涉及的延遲。爲了簡單起見,我可能會先重新使用1個連接,如果發現不足,嘗試連接池。如果延遲非常高,我只會求助於並行化。

如果您不再使用一次性物品,請務必處置一次性物品 - 連接通常需要進行處理。

+0

它更簡單,更健壯,可擴展*不使用單個連接,而是在使用數據庫後立即打開和關閉連接。開放連接是一種保持事務和鎖定打開的連接,更不用說它一次只能執行一個命令。最終阻止多個線程都很容易等待現有命令完成 – 2014-10-20 09:49:10