2016-06-11 90 views
0

我想制定出一種有效的方式來異步調用20-30文件的Powershell cmdlet。 儘管下面的代碼正在運行,但對於每個處理過的文件都會運行Import-Module步驟。不幸的是,這個模塊需要3到4秒才能導入。C#異步調用PowerShell,但只導入模塊一次

在網上搜索我可以找到對RunspacePools & InitialSessionState的引用,但是在嘗試創建CreateRunspacePool過載中所需的PSHost對象時遇到了問題。

任何幫助,將不勝感激。

感謝

加文

。從我的應用程序

代碼示例:

我使用的是並行的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(); 
    } 
} 
+0

[PowerShell的 - 如何導入模塊的運行空間]的可能的複製(http://stackoverflow.com/questions/6266108/powershell-how-to-import-module-in-a-runspace) – user4317867

+0

嘗試使用[here]中的代碼(https://communary.net/2014/11/24/runspaces-made-simple /)使用InitialSessionState爲RunSpacePools加載模塊。 – user4317867

+0

謝謝,在帖子上的答案仍然在foreach循環中爲每個項目導入模塊一次。 雖然有一個鏈接到描述我需要的信息的博客。所以謝謝你指點我正確的方向。 – Gavin

回答

0

因爲它已經在評論中解釋說,這不會因爲PSJobs對象序列化工作,並在自己的工作在一個單獨的進程中運行。

你可以做的是創建具有InitialSessionState有進口模塊RunspacePool

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(); 
    } 
}