[英]C# calling PowerShell asynchronously but only importing modules once
我正在嘗試找出一種異步調用20-30個文件的Powershell cmdlet的有效方法。 盡管下面的代碼有效,但是對每個處理的文件都運行“導入模塊”步驟。 不幸的是,此模塊需要3到4秒鍾才能導入。
在網上搜索時,我可以找到對RunspacePools和InitialSessionState的引用,但是在嘗試創建PSHost對象時遇到了問題,而CreateRunspacePool重載中則需要這樣做。
任何幫助,將不勝感激。
謝謝
加文
。
。
我的應用程序中的代碼示例:
我正在使用Parallel ForEach在線程之間分發文件。
Parallel.ForEach(files, (currentFile) =>
{
ProcessFile(currentfile);
});
private void ProcessFile(string filepath)
{
//
// Some non powershell related code removed for simplicity
//
// Start PS Session, Import-Module and Process file
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript("param($path) Import-Module MyModule; Process-File -Path $path");
PowerShellInstance.AddParameter("path", filepath);
PowerShellInstance.Invoke();
}
}
正如注釋中已經解釋的那樣,這不適用於PSJobs
因為對象已序列化且作業本身在單獨的進程中運行。
你可以做的就是創建一個RunspacePool
與InitialSessionState
有進口的模塊:
private RunspacePool rsPool;
public void ProcessFiles(string[] files)
{
// Set up InitialSessionState
InitialSessionState initState = InitialSessionState.Create();
initState.ImportPSModule(new string[] { "MyModule" });
initState.LanguageMode = PSLanguageMode.FullLanguage;
// Set up the RunspacePool
rsPool = RunspaceFactory.CreateRunspacePool(initialSessionState: initState);
rsPool.SetMinRunspaces(1);
rsPool.SetMaxRunspaces(8);
rsPool.Open();
// Run ForEach()
Parallel.ForEach(files, ProcessFile);
}
private void ProcessFile(string filepath)
{
// Start PS Session and Process file
using (PowerShell PowerShellInstance = PowerShell.Create())
{
// Assign the instance to the RunspacePool
PowerShellInstance.RunspacePool = rsPool;
// Run your script, MyModule has already been imported
PowerShellInstance.AddScript("param($path) Process-File @PSBoundParameters").AddParameter("path", filepath);
PowerShellInstance.Invoke();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.