启动多个进程并等待它们完成

问题描述 投票:0回答:2

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

我的代码应该做什么?:我有多个Bots在VM / Remoteclients上运行以模拟一些流量,并且在操作机器后对它们的行为进行一些研究并且需要几个小时才能完成。这是由我的主机完成的,它使用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 

}

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

我希望有人可以帮我弄清楚我做错了什么。

// Update 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
c# process async-await
2个回答
1
投票

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

Thread.Join Doc

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

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

任务。当所有Doc

创建将在所有提供的任务完成后完成的任务。

这个不等。它正在创建另一个继续正常的任务。

Task.WhenAll.Wait Doc

等待任务完成执行。

这一个采取上面的任务创建并等待其终止。 (Task.WaitAll会得到相同的)

你可以做什么:

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

Task.WaitAll(tl.ToArray());

如果您不想阻止当前线程:

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

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


0
投票

感谢大家的帮助。我在周末想出来了。

我从startBot改变了设计,让它返回一个Task,然后await就可以了。

© www.soinside.com 2019 - 2024. All rights reserved.