2010-08-25 27 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