Я вызываю скрипт powershell из C #. Сценарий довольно маленький и представляет собой «gps; $ host.SetShouldExit (9)», который обрабатывает список, а затем отправляет обратно код выхода, который будет захвачен объектом PSHost.
Проблема, с которой я столкнулся, заключается в том, что когда конвейер был остановлен и утилизирован, коллекция PSHost считывателя выходных данных все еще записывается и заполняется. Поэтому, когда я пытаюсь скопировать его в свой собственный выходной объект, он обнуляется с OutOfMemoryException, когда я пытаюсь перебрать его. Иногда это будет, кроме как с измененным сообщением. Вот код.
private void ProcessAndExecuteBlock(ScriptBlock Block)
{
Collection<PSObject> PSCollection = new Collection<PSObject>();
Collection<Object> PSErrorCollection = new Collection<Object>();
Boolean Error = false;
int ExitCode=0;
//Send for exection.
ExecuteScript(Block.Script);
// Process the waithandles.
while (PExecutor.PLine.PipelineStateInfo.State == PipelineState.Running)
{
// Wait for either error or data waithandle.
switch (WaitHandle.WaitAny(PExecutor.Hand))
{
// Data
case 0:
Collection<PSObject> data = PExecutor.PLine.Output.NonBlockingRead();
if (data.Count > 0)
{
for (int cnt = 0; cnt <= (data.Count-1); cnt++)
{
PSCollection.Add(data[cnt]);
}
}
// Check to see if the pipeline has been closed.
if (PExecutor.PLine.Output.EndOfPipeline)
{
// Bring back the exit code.
ExitCode = RHost.ExitCode;
}
break;
case 1:
Collection<object> Errordata = PExecutor.PLine.Error.NonBlockingRead();
if (Errordata.Count > 0)
{
Error = true;
for (int count = 0; count <= (Errordata.Count - 1); count++)
{
PSErrorCollection.Add(Errordata[count]);
}
}
break;
}
}
PExecutor.Stop();
// Create the Execution Return block
ExecutionResults ER = new ExecutionResults(Block.RuleGuid,Block.SubRuleGuid, Block.MessageIdentfier);
ER.ExitCode = ExitCode;
// Add in the data results.
lock (ReadSync)
{
if (PSCollection.Count > 0)
{
ER.DataAdd(PSCollection);
}
}
// Add in the error data if any.
if (Error)
{
if (PSErrorCollection.Count > 0)
{
ER.ErrorAdd(PSErrorCollection);
}
else
{
ER.InError = true;
}
}
// We have finished, so enque the block back.
EnQueueOutput(ER);
}
и это класс PipelineExecutor, который настраивает конвейер для выполнения.
public class PipelineExecutor
{
private Pipeline pipeline;
private WaitHandle[] Handles;
public Pipeline PLine
{
get { return pipeline; }
}
public WaitHandle[] Hand
{
get { return Handles; }
}
public PipelineExecutor(Runspace runSpace, string command)
{
pipeline = runSpace.CreatePipeline(command);
Handles = new WaitHandle[2];
Handles[0] = pipeline.Output.WaitHandle;
Handles[1] = pipeline.Error.WaitHandle;
}
public void Start()
{
if (pipeline.PipelineStateInfo.State == PipelineState.NotStarted)
{
pipeline.Input.Close();
pipeline.InvokeAsync();
}
}
public void Stop()
{
pipeline.StopAsync();
}
}
Это метод DataAdd, где возникает исключение.
public void DataAdd(Collection<PSObject> Data)
{
foreach (PSObject Ps in Data)
{
Data.Add(Ps);
}
}
Я поместил цикл for в Data.Add, и Collection заполнился 600k +, поэтому кажется, что команда gps все еще выполняется, но почему. Любые идеи.
Заранее спасибо.