Reputation: 6518
I have a class that awaits an asynchronous thread to return. What I do is launch a while loop and check every second where it's at.
public class AsychronousThingy
{
public bool IsComplete{get;private set;}
public string Result {get;private set;}
public void StartDoingThings(){
IsComplete = false;
// kick of an asynchronous thread to do stuff...
}
private void OnComplete(){
IsComplete = true;
Result = "magical result";
}
}
public class ActionExecutor{
public async Task<CustomThingyTaskResult> DoStuff(){
var thing = new AsychronousThingy();
thing.StartDoingThings();
// this returns instantly...?
while(!thing.IsComplete){
await Task.Delay(1000);
}
// do stuff once the 'thing' is complete.
return new CustomThingyTaskResult(thing.Result);
}
}
class Program{
public static void Main(){
var exec = new ActionExecutor();
var returnValue = await exec.DoStuff();
}
}
I'm unsure why it is returning instantly. Is this an issue - can you not use Task.Delay inside a loop? Odd.
I am sure that this is returning before it is complete as when I console.writeline
from the OnComplete event of my async class it actually completes after my main method has finished.
Upvotes: 0
Views: 856
Reputation: 458
Your Main()
function is void
. As a result, after first hit to actual async
action (in your example it is await Task.Delay(1000)
) it returns control to its caller.
So, you can change the signature of Main()
function as follows:
public static async Task Main() {...}
And then await on it.
Or, as alternative, you may not use async
keyword on it and use old Wait/Result:
public static void Main()
{
...
var returnValue = exec.DoStuff().Result;
// Or, if there is a SynchronizationContext
returnValue = Task.Run(() => exec.DoStuff()).Result; // This may prevent dead locks that can occur in previous line
}
Upvotes: 1
Reputation: 46607
Because DoStuff()
is async, it finishes asynchronously when called. This explains why the main
method has already returned when the asynchronous action completes. However, since DoStuff
returns void
, you cannot await
it as you would normally do. You can change the return type to Task
though, and then await
it.
There is nothing wrong about awaiting in a loop, except that it is more efficient to use events (or other synchronization mechanisms). Also, AsynchronousThingy
could likely be formulated in terms of a Task
as well :-)
Upvotes: 3