2012-07-30 83 views
1

我創建了一個ThreadManager類,該類處理Threads,其任務是添加新的threads並清理死者threads。但是,創建的threads仍然爲aliveThreadState.WaitSleepJoin狀態。我已經檢查過身體已經成功完成執行。有任何想法嗎?線程在執行後保持存活

public bool TryAddThread(ThreadStart threadBody, ThreadStartInfo startInfo) 
    { 
     bool success = false; 

     // Validate arguments 
     if (threadBody == null || startInfo == null) 
     { 
      return false; 
     } 

     if (!Monitor.TryEnter(_lock) || !_allowNewThreads) 
     { 
      return false; 
     } 

     try 
     { 
      Thread newThread = new Thread(threadBody); 

      StartThread(newThread, null, startInfo); 

      success = true; 
     } 
     finally 
     { 
      Monitor.Exit(_lock); 
     } 

     return success; 
    } 

    private void StartThread(Thread newThread, object threadParams, ThreadStartInfo startInfo) 
    { 
     if (newThread == null || startInfo == null) 
     { 
      return; 
     } 

     // Apply start info 
     newThread.Name = startInfo.Name; 
     newThread.SetApartmentState(startInfo.ApartmentState); 
     newThread.IsBackground = startInfo.IsBackground; 

     if (threadParams == null) 
     { 
      newThread.Start(); 
     } 
     else 
     { 
      newThread.Start(threadParams); 
     } 

     _threads.Add(newThread); 

     RemoveDeadThreads(); 
    } 

    public void RemoveDeadThreads() 
    { 
     _threads.RemoveAll(t => (!t.IsAlive)); 
    } 

執行在主線程:

public void InsertAsync(AP p, APr pr) 
    { 
     ParameterizedThreadStart thread = new ParameterizedThreadStart(InsertPr); 
     List<object> parameters = new List<object>(); 

     // Create new controller. Must be before the thread to avoid cross-thread operation exception. 
     PageController controller = new PageController(); 
     controller.Initialize(siteWebBrowser); 

     parameters.Add(controller); 
     parameters.Add(p); 
     parameters.Add(pr); 
     parameters.Add(_session); 

     // If the thread cannot start notify listeners 
     if (!_threadManager.TryAddThread(thread, parameters, new ThreadStartInfo("InsertAsync", ApartmentState.STA, true)) && ThreadCreationFailed != null) 
     { 
      _logger.Error("InsertAsync: Could not start thread."); 
      ThreadCreationFailed(); 
     } 

    } 

    private static void InsertPr(object o) 
    { 
     try 
     { 
      _logger.Debug("Thread start - InsertPr"); 

      List<object> parameters = (List<object>)o; 
      PageController controller = (PageController)parameters[0]; 
      AP p = (AP)parameters[1]; 
      APr pr = (APr)parameters[2]; 
      Session session = (Session)parameters[3]; 

      if (patient == null) 
      { 
       throw new ArgumentException("Null patient."); 
      } 

      session.WaitForHistorySynchronizationSuspension(); 

      if (Program.ShouldAbortBackgroundOperations) 
      { 
       throw new Exception("Aborting.."); 
      } 

      session.DoingSomeJob = true; 



      controller.ClearCurrent(); 

      controller.GoToHomePage(3, true); 

      controller.ClickNew(); 


      controller.SearchForP(p.Id); 


      try 
      { 
       controller.WaitUntilDivExists(Constants.NewPrContainerDivId); 
      } 
      catch (Exception) 
      { 
       _logger.Error("InsertAsync: Error while waiting for div '" + Constants.NewPrContainerDivId + "' to appear."); 
       throw; 
      } 

      if (PrInsertionCompleted != null) 
      { 
       PrInsertionCompleted(); 
      } 
     } 
     catch (Exception ex) 
     { 
      _logger.ErrorException("InsertAsync", ex); 

      if (InsertionFailed != null) 
      { 
       InsertionFailed(Constants.MessageFailed); 
      } 
     } 
    } 
+0

爲什麼不使用線程池? – 2012-07-30 15:17:54

+0

幾件事情:1)爲什麼不使用ThreadPool? 2)線程狀態取決於這些線程中發生了什麼(這些代理中是否有任何睡眠或等待句柄?)3)如果'_allowNewThreads'爲false,那麼您有可能永遠不會釋放該鎖你應該使用'lock'語句) – SomeWritesReserved 2012-07-30 15:18:59

+0

沒有線程代碼的執行,很難回答這個問題的細節。 – 2012-07-30 15:23:38

回答

1

WaitSleepJoin意味着線程被阻塞本身與呼叫爲鎖定(Monitor.Enter),到了Thread.Sleep一個呼叫,或將呼叫Thread.Join或其他一些線程同步對象。

也許如果您提供引起此線程狀態的示例線程入口點,則有人可以提供更詳細的答案。

+0

我可以向你保證,線程正文執行完畢。我已經通過它進行了調試,並且一切正常(很遺憾,我無法提供詳細的代碼)。我看到最後一個'}執行,並且線程完成的工作如預期的那樣是100%。該鎖也被釋放,但線程仍處於睡眠/等待/加入狀態。 – iCantSeeSharp 2012-07-30 15:26:03

+0

嗯,我發現很難相信系統對你說謊......我發現系統更可能是正確的,並且你的線程實際上被阻塞了。沒有看到代碼,我們無法確定。 – 2012-07-30 15:32:01

+0

如果我運行一個簡單退出的線程的快速示例,狀態將停止,而不是WaitSleepJoin。 – 2012-07-30 15:38:04

2

當程序的主啓動線程終止時,您可以要求CLR自動爲您中止線程。但是,這是不是自動,您必須顯式設置線程的IsBackground屬性爲true。線程池線程自動打開該屬性。

+0

這是目前發生的情況。應用程序自動關閉'Threads',但我想知道爲什麼會發生這種情況?在實際啓動'Thread'之前釋放鎖定會是一個不錯的主意嗎? – iCantSeeSharp 2012-07-30 15:31:26

+0

我不知道你的意思。當*開始*線程與您的程序終止有關時,釋放鎖是什麼?當你的程序結束時,鎖定狀態根本不重要。 – 2012-07-30 15:36:24

+0

問題是關閉應用程序退出時的線程。無論如何,我知道他們被終止了。問題是他們在身體迴歸後仍然「活着」。 – iCantSeeSharp 2012-07-30 15:39:24