我正在尝试启动多个任务,这将在远程机器上启动一个进程。他们得出结论后,应该发送邮件。
我的代码应该做什么?:我在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
答案 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,然后等待工作完成。