管道可以在同一运行空间同时运行? [英] Can Pipelines run concurrently in the same Runspace?

查看:156
本文介绍了管道可以在同一运行空间同时运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在相同的运行空间平行运行两个cmdlet。我使用C#

How to run two cmdlets parallely in same Runspace. I am using C#.

InitialSessionState iss = InitialSessionState.CreateDefault();
iss.AuthorizationManager = new AuthorizationManager("MyShellId");
iss.ImportPSModule(new string[] { "MSOnline" });
Runspace powerShellRunspace = RunspaceFactory.CreateRunspace(iss);

在两个线程,我将运行在同一运行空间的cmdlet。

In two threads, i will run cmdlets using the same runspace.

Pipeline pipeLine = powerShellRunspace.CreatePipeline();
pipeLine.Commands.Add(shellCommand);
pipeLine.Input.Close();
pipeLine.Invoke();
pipeLine.Output.DataReady += new EventHandler(processData);    //processData is a method which processes data emitted by pipeline as and when it comes to avoid out of memory
if (pipeLine.Error != null && pipeLine.Error.Count > 0) {
    Collection<Object> errors = (Collection<Object>)(pipeLine.Error.ReadToEnd());
    //process those errors
}



但是,当两个线程同时使用同样的运行空间来运行的cmdlet。我得到的例外,因为管道管道已经在执行时不执行。管道不能同时执行。

But when two threads simultaneously using the same runspace to run cmdlets. I am getting exception, "Pipeline not executed because a pipeline is already executing. Pipelines cannot be executed concurrently."

我需要使用相同的运行空间性能方面的原因。如何实现我的目标?

I need to use same runspace for performance reasons. How to achieve my objective?

推荐答案

您是否看了的 System.Management.Automation.Runspaces.RunspacePool 类?使用它和InitialSessionState可以帮助从模块导入消除的开销,因为它只是运行空间每每做一次泳池,而不是。如果你正在寻找的PowerShell命令这里是一个非常基本的,没有生产就绪例如异步执行:(注意我不是在使用Visual Studio的计算机,但是这应该是正确的)

Have you looked at the System.Management.Automation.Runspaces.RunspacePool class? Using it and the InitialSessionState can assist with eliminating overhead from module imports as it is only done once per pool and not per runspace. If you are looking for asynchronous execution of powershell commands here is a very basic, not production-ready example: (note I am not at a computer with Visual Studio but this should be right)

InitialSessionState iss = InitialSessionState.CreateDefault();
iss.AuthorizationManager = new AuthorizationManager("MyShellId");
iss.ImportPSModule(new string[] { "MSOnline" });
#set commands we want to run concurrently
string[] commands = new string[4] {
    "Start-Sleep -Seconds 5; 'Hi from #1'",
    "Start-Sleep -Seconds 7; 'Hi from #2'",
    "Start-Sleep -Seconds 3; 'Hi from #3'",
    "throw 'Danger Will Robinson'"
};
Dictionary<PowerShell, IAsyncResult> dict = new Dictionary<PowerShell, IAsyncResult>();
//this loads the InitialStateSession for all instances
//Note you can set the minimum and maximum number of runspaces as well
using(RunspacePool rsp = RunspaceFactory.CreateRunspacePool(iss))
{
    rsp.SetMinRunspaces(5);
    rsp.SetMaxRunspaces(10);
    rsp.Open();
    foreach(string cmd in commands)
    {
        PowerShell ps = PowerShell.Create();
        ps.AddScript(cmd);
        ps.RunspacePool = rsp;
        //Add parameters if needed with ps.AddParameter or ps.AddArgument
        dict.Add(ps,ps.BeginInvoke());            
    }
    do{
        List<PowerShell> toBeRemoved = new List<PowerShell>();
        foreach(KeyValuePair<PowerShell, IAsyncResult> kvp in dict)
        {
            if(kvp.Value.IsCompleted)
            {
                try
                {
                    PSDataCollection<PSObject> objs = kvp.Key.EndInvoke(kvp.Value);
                    foreach(PSObject obj in objs)
                    {
                        Console.WriteLine(obj);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
                finally
                {
                    toBeRemoved.Add(kvp.Key);
                }
            }
        }
        foreach(PowerShell item in toBeRemoved)
        {
            dict.Remove(item);
        }
        //Wait before we check again
        Thread.Sleep(200);
    } while (dict.Count > 0)
    rsp.Close();
}
//Added to keep console open
Console.Read();

这应该给:

Hi from #3
Hi from #1
Hi from #2

这篇关于管道可以在同一运行空间同时运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆