2014-10-20 101 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