I'm new to c# async await mechanism. I have checked all the previous examples of async, await but none of them is exactly like mine. what I would like to do? I have a foreach loop and I would like to stop it on a certain rule, do some stuff and continue running by clicking on a button. Here is simple code example:
private void RunConvert() // START
{
foreach (PartSettings File in PartsFromXLS) // RUNING THE FOREACH LOOP ON A LIST
{
ProcessSinglePart(PathStep, PathMCX);
}
}
public static async void ProcessSinglePart(string PartPathToRead, string PartPathToSave)
{
// DO SOME STUFF BEFORE THE CHECK
if (PartLength < PartWidth) // SOME CHECK VALUES
{
await WhenClicked(); //HERE I WOULD LIKE TO WAIT FOR BUTTON CLICK
}
//DO SOME STUFF AFTER THE CHECK
}
private void GeometryOK_Click(object sender, EventArgs e)
{
// I WOULD LIKE TO WAIT FOR THIS CLICK
}
await suspends execution of a method until the argument (which must be a Tasklike, in practice, its just a Task or Task<T>) completes. Your issue is actually one that I've run into a number of times:
How to asynchronously wait for some event to be fired
In your case "some event" is a button click. Luckily, TaskCompletionSource<T> (hereafter, TCS) is pretty much ideal for solving this. First declare a TCS at the class level:
private TaskCompletionSource<bool> clickWaitTask;
There's no non-generic version of a TCS so I usually just use bool. We don't actually care about the data in this case. Then your method looks like this (explanation to follow):
public static async void ProcessSinglePart(string PartPathToRead, string PartPathToSave)
{
// DO SOME STUFF BEFORE THE CHECK
clickWaitTask = new TaskCompletionSource<bool>();
if (PartLength < PartWidth) // SOME CHECK VALUES
{
await clickWaitTask.Task;
}
//DO SOME STUFF AFTER THE CHECK
}
You create a new TCS so that each time this logic is run, it will wait for the click to occur. Then you await the Task property (which is, in fact, a Task<T>). That task will only complete when TrySetResult is called on the TCS object. Do that in your button click handler (or command handler for WPF):
clickWaitTask.TrySetResult(true); //Value does not matter
As a commenter noted, you shouldn't use async void unless you are in a event handler, and should have try/catch around the method in that case to avoid some nastiness with unhandled exceptions. I'm also extremely wary of your public static but that's a separate problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With