我有这项服务,当收到请求时,运行 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;
}
}
方法 Invoke 返回 powershell 脚本返回的所有结果。
一切都很好。只要它在单线程中运行。由于我们调用的某些 powershell 脚本可能需要长达一个小时才能完成,并且我们不希望服务在这段时间内什么也不做,因此我们决定采用多线程。
不幸的是Powershell类不是线程安全的,导致严重的内存泄漏和CPU消耗率。但是,如果我在 Invoke 方法上使用锁定,这将意味着我们采用多线程的整个想法将付之东流。
有什么想法如何解决这个问题吗?
您可以使用BeginInvoke()
的方法PowerShell
类而不是Invoke()
你使用的。在这种情况下,您异步执行脚本并且不会阻塞调用线程。但你也必须回顾整个场景。您的旧同步方法返回的结果可以在调用后立即轻松使用。在新的异步方法中,这是不可能以同样的方式实现的。
see
http://msdn.microsoft.com/en-us/library/system.management.automation.powershell.begininvoke http://msdn.microsoft.com/en-us/library/system.management.automation.powershell.begininvoke
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)