执行多个CMD任务并异步更新

时间:2015-09-19 00:28:08

标签: c# multithreading asynchronous cmd

我正在实现一个C#应用程序。我需要同时在多台远程机器上执行程序。为此,我在PSExec上使用CMD进行多线程处理。基本上,对于每台机器,我启动一个启动CMD进程的线程。根据远程执行程序的结果,我想要采取行动或杀死它,如果它需要超过x分钟(希望这是有道理的)。

我遇到的问题是,除了使用WaitForExit之外,我真的不知道如何控制进程运行了多长时间,这实际上并没有让我像多线程一样等到CMD来电结束后才会等待。

我确信必须有办法做到这一点,但我无法弄明白。有人可以帮帮我吗?

这是我的代码(我是c#编码的新手,所以可能不是最好的代码,随便纠正它认为不对的任何部分):

public async void BulkExecution()
{
    //Some code            
    foreach (string machine in Machines)
    {
        //more code to work out the CMDline and other duties.
        var result = Task.Factory.StartNew(r => ExecutePsexec((string)r, RunBeforeKillMsec), CMDLine);
        await result;
    }
    //More Code
}

private static void ExecutePsexec(string CMDline, int RunBeforeKillMsec)
{   
    Process compiler = new Process();
    compiler.StartInfo.FileName = "psexec.exe";
    compiler.StartInfo.Arguments = CMDline;
    compiler.StartInfo.UseShellExecute = false;
    compiler.StartInfo.RedirectStandardOutput = true;
    compiler.Start();

    if (!compiler.WaitForExit(RunBeforeKillMsec))
    {
        ExecutePSKill(CMDline);
    }
    else
    {
        //Some Actions here
        Common.Log(LogFile, CMDline.Split(' ')[0] + " finished successfully");                
    }
}

2 个答案:

答案 0 :(得分:1)

ExecutePsexec在单独的任务中运行。所有这些任务都是独立的。等待结果就是对它们进行排序。删除它。

答案 1 :(得分:0)

异步void方法should be avoided。您应该更改BulkExecution方法的签名以返回Task,以便可以await并处理可能发生的任何异常。在方法内部,为每台计算机创建一个Task,然后使用Task.WhenAll方法等待所有任务:

public async Task BulkExecution()
{
    //Some code            
    Task[] tasks = Machines.Select(machine =>
    {
        //more code to work out the CMDline and other duties.
        return Task.Run(r => ExecutePsexec(CMDLine, ExecutionTimeoutMsec));
    }).ToArray();
    await Task.WhenAll(tasks);
    //More Code
}