After looking around on both Async/Await and Threading, I'm still unsure of the right way to apply it to my situation. No matter the variation that I try my UI still hangs because I don't seem to be calling my desired function asynchronously, additionally, I may in fact need threading for my solution.
What I'm trying to do: I have a WPF application on which there is a button that I would like to start an operation that still allows interaction with the program, through UI or otherwise. Once a condition is met that is determined outside of this function, the function should end. To me this sounds fairly standard but I have a feeling I'm misunderstanding something and I've implemented it incorrectly.
What I have right now:
private async void start_button_Click(object sender, RoutedEventArgs e)
{
await StaticClass.MyFunction();
}
private void stop_button_Click(object sender, RoutedEventArgs e)
{
StaticClass.stopFlag = true;
}
public static Task<int> myFunction()
{
//Stuff Happens
while(StaticClass.stopFlag == false)
//Do Stuff
//Stuff Happens
return Task.FromResult(1) //I know this is bad, part of the reason I'm asking
}
I was hoping for some guidance on if I'm approaching this the right way and any insight on what I'm doing wrong.
You've definitely implemented it incorrectly. You're returning a Task<int>
, but only once all the work has already been done.
It seems to me that you should probably just have a synchronous method:
private static void MyFunction()
{
// Loop in here
}
Then start a task for it like this:
Task task = Task.Run((Action) MyFunction);
You can then await that task if you want - although in the example you've given, there's no point in doing so, as you're not doing anything after the await
anyway.
I'd also agree with Reed that using a CancellationToken
would be cleaner than a static flag somewhere else.
You did misunderstand.
public static Task<int> myFunction()
{
//Stuff Happens
while(StaticClass.stopFlag == false)
//Do Stuff
//Stuff Happens
return Task.FromResult(1) //I know this is bad, part of the reason I'm asking
}
All of that code still happens in the intial await StaticClass.MyFunction();
call, it never returns control to the caller. What you need to do is put the loop portion in to a separate thread.
public static async Task myFunction()
{
//Stuff Happens on the original UI thread
await Task.Run(() => //This code runs on a new thread, control is returned to the caller on the UI thread.
{
while(StaticClass.stopFlag == false)
//Do Stuff
});
//Stuff Happens on the original UI thread after the loop exits.
}
Instead of trying to use a bool
for this, you should consider using the managed cancellation framework built into the framework.
Basically, you'd build a CancellationTokenSource
, and pass a CancellationToken
to your method which could be used to handle cancellation.
Finally, your current method will never get off the UI thread. You'd need to use Task.Run
or similar to move the method to the ThreadPool if you don't want to block the UI.
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