启动多个过程,直到完成

时间:2019-02-14 15:48:27

标签: c# process async-await

我正在尝试启动多个任务,这将在远程机器上启动一个进程。他们得出结论后,应该发送邮件。

我的代码应该做什么?:我在VM / Remoteclients上运行多个Bot,以模拟一些流量,并在操纵机器后对其行为进行了一些研究,这需要数小时才能完成。这是由使用ps工具在其上远程运行脚本的主机完成的。基本上,我启动一个psexe来启动我的机器人,并启动一个psexe来“监视”该机器人的输出。到现在为止,我使用4个程序让脚本在4台计算机上运行,​​而一个程序则负责完成这4个任务,因此它们可能会向我发送一封邮件,说明该任务已完成,并且有错误或类似错误。那。而且很烦人的是总是在4个解决方案中更改代码^^,所以尽管我可以使它异步运行,但是在课堂上我们只讨论了这样的概念可能会如何工作,现在我在为的不同概念而苦苦挣扎。净如何实现它。下面,我提供了我的代码的模型。

void mainClass(){
   doWithThreads(); // this works
   doWithTasks(); // this dosnt work
   doWithTaskAndWait(); // this works again
}

void doWithThreads(){
   Thread t1 = new Thread(() => startBot("Bot1"));
   t1.start();   
   Thread t2 = new Thread(() => startBot("Bot2"));
   t2.start();
   t1.join();
   t2.join();
   sendMail();
}

void async doWithTasks(){
   List<Task> tl = new List<Task>();
   tl.add(Task.Factory.Startnew(() => startBot("Bot3"));
   tl.add(Task.Factory.Startnew(() => startBot("Bot4"));
   await Task.WhenAll(tl); // jumps instantly to sendMail and Task in TL are never started
   sendMail();
}

void doWithTaskAndWait(){
   List<Task> tl = new List<Task>();
   tl.add(Task.Factory.Startnew(() => startBot("Bot5"));
   tl.add(Task.Factory.Startnew(() => startBot("Bot6"));
   Task.WhenAll(tl).Wait(); //I think this works bc its again busy waiting
   sendMail();
}

void startBot(string x){
   Process a = ... //pstoolsconfig
   Process check = ... //pstoolsconfig 
   a.start();
   check.start() // this one checks the logfile of process a
   while(!check.StandardError.ReadToEnd().Contains(x + " has finished")){
      check.start(); //should simulate busy waiting
      thread.sleep(1000) //wait a sec
   }//as soon it finds the phrases "BotX has finished" in the logfile it should be done with his job 

}

不幸的是,我没有任何人可以问这个问题,也不知道为什么异步/等待方法不起作用。我的想法是,startBot方法返回void,并且bc永远无法“确认”它已完成运行。而且我认为thread.join和task.whenall.wait就像是繁忙的等待操作,会阻塞调度程序上的所有其他内容。但也许我很幸运,这些方法在调度程序中很快找到了一个位置,并且比sendmail更快地执行。

我希望有人能帮助我弄清楚我在做错什么。

//更新1:这就是doWithTask的行为

List<Task> tl = new List<Task>();
tl.add(Task.Factory.Startnew(() => startBot("Bot3"));
Console.WriteLine(tl.elementat(0).status)); // running 
Task.WhenAll (tl).ContineWith(t => sendMail());
Console.WriteLine(tl.elementat(0).status)); // running
//end of code exe closed

2 个答案:

答案 0 :(得分:1)

让我们看看为什么它会像现在这样工作:

线程。加入 Doc

  

阻塞调用线程,直到此实例表示的线程终止为止...

在继续sendMail()之前,它“等待”线程(t1,t2)终止。

任务。WhenAll Doc

  

创建一个任务,该任务将在所有提供的任务完成时完成。

这个不等。它正在创建另一个任务,并且照常继续进行。

Task.WhenAll.Wait (任务全部等待) Doc

  

等待任务完成执行。

此任务将上面的Task创建并等待其终止。 (Task.WaitAll可以达到同样的效果)

您可以做什么:

如果您要阻止当前线程直到完成:

Task.WaitAll(tl.ToArray());

如果您要阻止当前线程:

Task.WhenAll(tl).ContinueWith(t => sendMail());
  

ContinueWith创建一个异步执行的延续   当目标任务完成时。

答案 1 :(得分:0)

谢谢大家的帮助。我在周末想通了。

我从startBot更改了设计,使其返回一个Task,然后等待工作完成。