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 did misunderstand.
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.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 aCancellationToken
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.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:
Then start a task for it like this:
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.As an alternative, you could look into using BackgroundWorker class to do the job, your UI will stay interactive.