Powershell endinvoke功能在重负载下卡住

时间:2015-03-24 04:04:56

标签: c# multithreading powershell

我的应用程序是用c#编写的,并使用Powershell类的.net库。它是多线程的,可以在runspacepool上同时执行一堆powershell脚本。 我使用的runspacepool大小为100.在执行每个脚本之前,我使用下面的代码创建一个到目标计算机的会话。 我使用BeginInvoke开始在管道中执行,并使用end-invoke来获取结果,包括会话。

    ps = PowerShell.Create()
    var sessionScript = new PSCommand();
    sessionScript.AddCommand(New-PSSession);
    sessionScript.AddParameter("ConnectionUri",  "http://192.xxx.x.xxx:5985";);
    sessionScript.AddParameter("AllowRedirection");
    var sessOpt = new System.Management.Automation.Remoting.PSSessionOption();
    sessOpt.OpenTimeout = new TimeSpan(0,0,0,0, 120000);
    sessOpt.CancelTimeout = new TimeSpan(0, 0, 0, 0,120000);
    sessionScript.AddParameter("SessionOption", sessOpt);
    var cred = new PSCredential(uName, password);
    sessionScript.AddParameter("Credential", cred);
    ps.Commands = sessionScript
    ps.RunSpacePool = mypool  ## size 100 created earlier
    asyncResult = ps.BeginInvoke();  
    resultsOut = ps.EndInvoke(asyncResult);

当我将并行执行会话数保持在100以下时,一切都很好。偶尔当我达到100及以上时,我注意到一两个线程(.net任务)被卡住了。我做了一些调试,发现线程被EndInvoke卡住了。即使在一周之后,电话也没有返回,线程仍然存在。

因此,我通过向此操作添加Timer来替换执行代码

    Timer taskTimer = new Timer(TaskHitTimeout, null , 120000, System.Threading.Timeout.Infinite);
    asyncResult = ps.BeginInvoke(); 
    while (true)
            {
                if (asyncResult.IsCompleted || this.isCancelled)
                    break;
                Thread.Sleep(200);
            }

    if (!this.isCancelled)
         resultsOut = ps.EndInvoke(asyncResult);

在TimerHandler中我将isCancelled设置为True

     private void TaskHitTimeout(Object statusCode)
     { this.isCancelled = True;}

这确实解决了我的问题。但我想了解为什么对EndInvoke的调用不会返回。我还能做些什么来改善这一点。如果其他人看到了类似的问题。

0 个答案:

没有答案