I'm trying to start multiple Task which will start a process on a remote maschine. After they concluded a mail should be send.
What should my Code do?: I have multiple Bots running on VMs/Remoteclients to simulate some traffic and im doing some research on their behavior after manipulating the machine and it takes hours to finish. This is done by my main machine that use ps tools to run scripts remotely on them. Basically I start one psexe to start my bot and a psexe to "watch" over the output of the bot. Until now I used 4 programs to let the script run on the 4 machines and one program that was looking after those 4 task if they have finish so it may send me a mail that the task have completed and if it had some errors or smth like that. And tbh its annoying to change always the code in 4 solutions^^ so I though I could make it run asynchrony but in class we only talked about the concept how smth like this may work and now I'm struggling with the different concepts of .net how to implement it. Below I provided a mockup of my code.
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
}
Unluckily I don't have anyone who I can ask about it and I don't have any idea why the async/await method doesn't work. My Idea is that the startBot method returns void and bc of this it never can "confirm" that it has finished to run. And the I think that the thread.join and the task.whenall.wait are like busy waiting operations that blocks everything else on the scheduler. But maybe I'm just lucky that those methods find very fast a spot on the scheduler and are executed "faster" then the sendmail.
I hope someone can help me to figure out what I'm doing wrong.
//Update 1:Thats the behavior of 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