2016-06-11 48 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(); 
    } 
}