2011-05-23 186 views
0

我遇到了一个问题,管理.NET 4.0 C#上的线程,而且我的线程知识还不足以解决它,所以我在这里发布它期望有人可以给我一些建议请。处理多线程的线程

的情况如下:

我们有C#4.0框架Windows服务:(1)通过插座连接到服务器以获得.PCM文件,(2),然后将其转换为一个.WAV文件,(3)通过电子邮件发送 - SMTP,最后(4)通知初始服务器它已成功发送。

已安装服务的服务器有8个处理器和8 GB或RAM。

为了允许多处理我已经用4个线程构建了服务,它们中的每一个都执行前面提到的每个任务。

在代码中,我对每个任务的类和方法,所以我创建线程和调用方法如下:

Thread eachThread = new Thread(object.PerformTask); 

里面每一个方法我有一个检查一个而如果的连接套接字处于活动状态,并根据其porpuse继续获取数据或处理数据。

while (_socket.Connected){ 
//perform task 
} 

的问题是,由于正在安装更多的服务(相同的Windows服务被复制和两个端点之间所指向的服务器通过插座来获取文件上)的CPU消耗急剧增加,每个服务继续运行,处理文件,但有一段时间CPU消耗太高,服务器崩溃。

问题是:你会建议我如何处理这种情况,我的意思是一般而言,处理这种高度要求的处理任务以避免服务器在CPU消耗中崩溃的好方法是什么?

谢谢。

PS .:如果有人需要关于该场景的更多细节,请告诉我。

编辑1

随着CPU崩溃我的意思是服务器过于缓慢,我们不得不重新启动它。

编辑2

我在这里张贴代码的某些部分,所以你可以得到它是如何编程的想法:

while(true){ 
      //starting the service  
      try 
      { 
       IPEndPoint endPoint = conn.SettingConnection(); 
       string id = _objProp.Parametros.IdApp; 

       using (socket = conn.Connect(endPoint)) 
       { 
        while (!socket.Connected) 
        { 
         _log.SetLog("INFO", "Conectando socket..."); 
         socket = conn.Connect(endPoint); 

         //if the connection failed, wait 5 seconds for a new try. 
         if (!socket.Connected) 
         { 
          Thread.Sleep(5000); 
         } 
        } 

        proInThread = new Thread(proIn.ThreadRun); 
        conInThread = new Thread(conIn.ThreadRun); 
        conOutThread = new Thread(conOut.ThreadRun); 

        proInThread.Start(); 
        conInThread.Start(); 
        conOutThread.Start(); 

        proInThread.Join(); 
        conInThread.Join(); 
        conOutThread.Join(); 
       } 
      } 
    } 

编辑3

  • 主题1

    while(_socket。连接) { 尝试 { } var conn = new AppConection(ref _objPropiedades);

       try 
           { 
            string message = conn.ReceiveMessage(_socket); 
            lock (((ICollection)_queue).SyncRoot) 
            { 
             _queue.Enqueue(message); 
             _syncEvents.NewItemEvent.Set(); 
             _syncEvents.NewResetEvent.Set(); 
            } 
            lock (((ICollection)_total_rec).SyncRoot) 
            { 
    
             _total_rec.Add("1"); 
            } 
           } 
           catch (SocketException ex) 
           { 
            //log exception 
    
           } 
           catch (IndexOutOfRangeException ex) 
           { 
            //log exception 
           } 
           catch (Exception ex) 
           { 
            //log exception 
    
           } 
           //message received 
    
          } 
          catch (Exception ex) 
          { 
           //logging error 
          } 
         } 
    
         //release ANY instance that could be using memory 
         _socket.Dispose(); 
         log = null; 
    
  • 线程2

    而(_socket.Connected) { 尝试{ _syncEvents.NewItemEventOut.WaitOne();

        if (_socket.Connected) 
            { 
             lock (((ICollection)_queue).SyncRoot) 
             { 
    
              total_queue = _queue.Count(); 
    
             } 
    
             int i = 0; 
             while (i < total_queue) 
             { 
              //EMail Emails; 
              string mail = ""; 
              lock (((ICollection)_queue).SyncRoot) 
              { 
    
               mail = _queue.Dequeue(); 
    
               i = i + 1; 
              } 
              try 
              { 
               conn.SendMessage(_socket, mail); 
               _syncEvents.NewResetEvent.Set(); 
              } 
              catch (SocketException ex) 
              { 
               //log exception 
              } 
             } 
            } 
            else 
            { 
             //log exception 
    
             _syncEvents.NewAbortEvent.Set(); 
             Thread.CurrentThread.Abort(); 
            } 
           } 
           catch (InvalidOperationException e) 
           { 
            //log exception 
           } 
           catch (Exception e) 
           { 
            //log exception 
           } 
         } 
    
         //release ANY instance that could be using memory 
         _socket.Dispose(); 
         conn = null; 
         log = null; 
    
  • 线程3

    而(_socket.Connected) {

       int total_queue = 0; 
           try 
          { 
           _syncEvents.NewItemEvent.WaitOne(); 
           lock (((ICollection) _queue).SyncRoot) 
           { 
            total_queue = _queue.Count(); 
           } 
           int i = 0; 
           while (i < total_queue) 
           { 
            if (mgthreads.GetThreatdAct() < 
    

    mgthreads.GetMaxThread()){ 字符串消息= “”; 锁(((ICollection的)_queue).SyncRoot) {

          message = _queue.Dequeue(); 
              i = i + 1; 
    
             } 
             count++; 
             lock (((ICollection) _queueO).SyncRoot) 
             { 
              app.SetParameters(_socket, _id, 
    

    消息,_queueO,_syncEvents, _total_Env,_total_err); }

         Thread producerThread = new 
    

    螺纹(app.ThreadJob){名称= “ProducerThread_” + DateTime.Now.ToString( “ddMMyyyyhhmmss”), 优先级= ThreadPriority.AboveNormal }; producerThread.Start();

         producerThread.Join(); 
    
             mgthreads.IncThreatdAct(producerThread); 
            } 
            mgthreads.DecThreatdAct(); 
           } 
           mgthreads.DecThreatdAct(); 
          } 
          catch (InvalidOperationException e) 
          { 
    
          } 
          catch (Exception e) 
          { 
    
          } 
          Thread.Sleep(500); 
         } 
    
         //release ANY instance that could be using memory 
         _socket.Dispose(); 
         app = null; 
         log = null; 
         mgthreads = null; 
    
  • 螺纹4

    MessageVO mesVo = fac.ParseMessageXml(_message);

+0

你能定义“服务器CPU消耗崩溃”吗? – Olaf 2011-05-23 17:24:39

+0

你能定义你的意思吗?“问题在于随着更多服务的安装”。这是否意味着更多的线程正在运行或更多的进程?线程如何确定要执行的任务? – usr 2011-05-23 17:32:08

+0

你可以定义多少“更多”。你的大部分线程听起来像是对我的串行操作,还是你在一个服务中处理了很多? – sra 2011-05-23 17:41:39

回答

0

我会降低线程的优先级,并有所有线程通过一个信号量限制并发到Environment.ProcessorCount。这不是一个完美的解决方案,但它听起来像是在这种情况下是足够的,而且很容易修复。

编辑:想想看,您必须将10个服务合并到一个进程中,否则您将无法集中控制正在运行的线程。如果你有10个独立的进程,他们不能协调。

+0

这是非常有用的,如果你的任务实际上需要长时间的纯cpu计算。 – Alireza 2011-05-23 17:28:55

+0

您发布的代码看起来不会不必要地旋转。我找不到它的问题。做到这一点:运行服务直到它变热,然后停止调试器,查看所有正在运行的脚本及其调用堆栈。你可能会发现一些有趣的东西。至少你会发现热点。 – usr 2011-05-23 17:53:25

+0

做了一个编辑... – usr 2011-05-23 18:04:17

0

由于CPU使用率高,通常应该不会崩溃。当任何线程正在等待远程发生的事件(例如远程服务器响应请求)时,该线程不使用cpu资源。但是实际上它正在做某些事情,因此它会相应地使用cpu。在你提到的任务中,没有固有的高CPU使用率(因为WAV文件的保存不需要复杂的算法),所以CPU的高使用率似乎是编程错误的标志。

+0

谢谢,我不知道。 – lidermin 2011-05-23 19:41:19