2011-12-30 140 views
4

我有一個服務,需要永遠運行,以監視一臺服務器。爲了做到這一點,我有5個任務需要由服務完成(目前5個,將有數百個)。OutOfMemory異常C#當使用線程

我創建了一個線程池,最多5個線程。有一個線程用來獲取任務的線程,然後每個線程處理任務,然後再次入隊。隊列包含具有5個小屬性的對象。

後的服務運行了一段時間,我得到一個OutOfMemoryException,在那裏我執行該行:

ThreadPool.QueueUserWorkItem(currentJob.ProcessJob, (object)timeToWwait); 

timeToWwait是一個int,我不使用它了。

的背景是這樣的:

 ThreadPool.SetMinThreads(0, 0); 
     ThreadPool.SetMaxThreads(5, 5); 
     while (true) 
     { 
      bool processJob = false; 
      bool checkedFrontEnd = false; 
      _qLock.EnterWriteLock(); 
      try 
      { 
       if (_jobQueue.Count > 0) 
       { 
        currentJob = _jobQueue.Dequeue(); 
        // currentJob.IsActive = true; 
        // processJob = true; 
       } 
      } 
      finally 
      { 
       _qLock.ExitWriteLock(); 
      } 
      ThreadPool.QueueUserWorkItem(currentJob.ProcessJob, (object)timeToWwait); 
      //currentJob.ProcessJob((object)timeToWwait); 


      _qLock.EnterWriteLock(); 
      try 
      { 
       _jobQueue.Enqueue(currentJob); 
      } 
      finally 
      { 
       _qLock.ExitWriteLock(); 
      } 

你有什麼建議嗎?

+1

請參閱關於在您的標題中包含您的問題和標籤簽名的常見問題。我已經修復了兩次,但我從中得到的2個代表是不值得再做的。 – 2011-12-30 04:47:41

回答

1

看起來您可能想要在工作線程完成後再次將作業排入隊列(至jobQueue)。想象一下,池中只有1個線程,jobQueue中只有1個線程,如果任務長時間運行,你的代碼會在同一個任務上多次執行ThreadPool.QueueUserWorkItem。另外我認爲如果在jobQueue中有一個作業(從上面的代碼看起來它會運行),你只想執行ThreadPool.QueueUserWorkItem。感謝有趣的問題。

+0

謝謝你對我的問題感興趣。你是對的。這真的解決了我的問題......終於。很有幫助。 – Adn11 2011-12-30 07:13:37

2

你的問題是你在前臺任務有機會完成之前排隊currentJob實例。你會想做這樣的事情,而不是:

 ThreadPool.QueueUserWorkItem((state) => 
             { 
              currentJob.ProcessJob(); 
              _qLock.EnterWriteLock(); 
              try 
              { 
               _jobQueue.Enqueue(currentJob); 
              } 
              finally 
              { 
               _qLock.ExitWriteLock(); 
              } 

             } 
      ); 
+0

非常感謝你幫助我。這確實解決了我的問題,並感謝您的建議。我會用這種方法。我只是想着一個新的設計,你的答案非常有幫助。 – Adn11 2011-12-30 07:11:05