2010-08-25 45 views
2

我有這種服務,當收到請求時,運行powershell命令並返回結果。這裏是調用者類代碼:如何使C#Powershell調用成員線程安全

public class PowerShellScript { 

    public PowerShellScript() { 
    } 

    public Object[] Invoke(String strScriptName, NameValueCollection nvcParams) { 
     Boolean bResult = true; 
     int n = 0; 
     Object[] objResult = null; 
     PowerShell ps = PowerShell.Create(); 
     String strScript = strScriptName; 

     for (n = 0; n < nvcParams.Count; n++) { 
      strScript += String.Format(" -{0} {1}", nvcParams.GetKey(n), nvcParams[n]); 
     } 

     //ps.AddScript(@"E:\snapins\Init-profile.ps1"); 
     ps.AddScript(strScript); 
     Collection<PSObject> colpsOutput = ps.Invoke(); 
     if (colpsOutput.Count > 0) 
      objResult = new Object[colpsOutput.Count]; 

     n = 0; 
     foreach (PSObject psOutput in colpsOutput) { 
      if (psOutput != null) { 
       try { 
        objResult[n] = psOutput.BaseObject; 
       } 
       catch (Exception ex) { 
        //exception should be handeled properly in powershell script 
       } 
      } 
      n++; 
     } 
     colpsOutput.Clear(); 
     ps.Dispose(); 

     return objResult; 
    } 
} 

方法調用返回由powershell腳本返回的所有結果。

一切都很好。只要這個在一個線程中運行。由於我們調用的某些PowerShell腳本可能需要一個小時才能完成,而且我們不希望服務在那段時間內什麼也不做,所以我們決定採用多線程。 不幸的是,Powershell類不是線程安全的,導致嚴重的內存泄漏和CPU燒錄率。但是,如果我在Invoke方法上使用鎖,這意味着我們爲什麼使用多線程的整個想法將會陷入困境。

任何想法如何解決這個問題?

回答

1

反正...在執行PowerShell命令時,我放棄了多線程。我創建了一個能夠執行PowerShell腳本的小程序。然後,每個線程爲該程序創建新的進程。我知道這是一個開銷,但它的工作原理。

基本上,Powershell類不是線程安全的。除了靜態變量(http://msdn.microsoft.com/en-us/library/system.management.automation.powershell%28VS.85%29.aspx)。

因此,嘗試通過單獨的線程調用多個腳本會導致內存泄漏和一些無法解釋的CPU使用率。我瘋狂的猜測是它沒有正確關閉。從多線程切換到多進程環境應該將事情弄清楚。但是,這意味着重大的政治變革。

1

您可以使用BeginInvoke()方法PowerShell類而不是您使用的Invoke()。在這種情況下,您可以異步執行腳本,並且不會阻止調用線程。但是你也必須檢查你的整個場景。您的舊同步方法返回可在調用後立即使用的結果。在新的異步方法中,這是不可能的。

看到 http://msdn.microsoft.com/en-us/library/system.management.automation.powershell.begininvoke

+0

絕妙的主意。將盡快嘗試。 請注意,看着這個例子,它應該沒有那麼大的區別 – 2010-08-25 07:34:42

+0

沒有。仍然是一個巨大的內存泄漏和CPU燒傷率。即使只有一個線程訪問它。事情是,當它運行在非線程的evnironment,它沒有一個小故障 – 2010-08-25 07:55:06

+0

嗯,那麼也許我誤解了你會得到什麼。資源(內存和CPU)將由您的任務以多線程或不線程方式使用。實際上,如果您同時運行多個任務,多線程方法會消耗更多的資源。順便說一句,「內存泄漏」究竟意味着什麼? – 2010-08-25 08:23:10