2

I am rewriting some of my component management to use async start methods. Sadly it looks like a call to an async method WITHOUT await, still does await the result?

Can anyone enlighten me?

I am calling:

public async Task StartAsync() {
    await DoStartProcessingAsync();
}

which in itself is calling a slow implementation of protected abstract Task DoStartProcessingAsync(); - slow because it dome some EF calls, then creates an appdomain etc. - takes "ages".

The actual call is done in the form:

x.StartAsync().Forget();

with "Forget" being a dummy function just to avoid the "no await" warning:

public static void Forget(this Task task) {
}

Sadly, this sequence - is waiting for the slow DoStartAsync method to complete, and I see no reason for that. I am quite old in C#, but quite new to async/await and I was under the impression that, unless I await for the async task - the method would complete. As such, I expected the call to StartAsyc().Forget() to return immediatly. INSTEAD stack trace shows the thread going all the way into the DoStartProcessingAsync() method without any async processing happening.

Anyone can enlighten me on my mistake?

12
  • 3
    Can you show DoStartProcessingAsync()? Just to make sure it's not only called Async but really is awaiting something and not working synchronously. Commented Feb 9, 2016 at 10:34
  • I think this is less about async and more about processing in the background ... for example the async Task Blah() { await Something(); } should be just the same as just Something() - this does not magically make it happen in the background Commented Feb 9, 2016 at 10:36
  • 1
    async methods will run synchronously till it reaches first await. If there is no await, it runs completely synchronously. Can you post the code of DoStartProcessingAsync? Commented Feb 9, 2016 at 10:36
  • 1
    I'm surprised if you don't want to await you are making your StartAsync async and inside awaiting DoStartProcessingAsync(). Why don't you just remove those particular keywords then do var result = x.StartAsync() and it should just work Commented Feb 9, 2016 at 10:37
  • 3
    @TomTom mere presence of async keyword doesn't automagically makes a method asynchronous. There needs to be a await keyword and the method you're awaiting should also be asynchronous. If you have time consuming parts in the method, then consider calling it in another thread i.e await Task.Run(()=> DoStartProcessingAsync()); Commented Feb 9, 2016 at 10:40

1 Answer 1

3

What your trying to achieve here is a fire and forget type mechanism. So async/await isn't really what you want. Your not wanting to await anything.

These are designed to free up threads for long running processes. Right now your returning a Task using an await and then "forgetting" it. So why return the Task at all?

Your freeing up the thread for the long running process, but your also queuing a process that ultimately does nothing (this is adding overhead that you could likely do without).

Simply doing this, would probably make more sense:

public void StartAsync() {
    Task.Run(() => DoStartProcessingAsync());
}

One thing to bear in mind is that your now using a ThreadPool thread not a UI thread (depending on what is actually calling this).

Sign up to request clarification or add additional context in comments.

5 Comments

I have rewritten Start to use return Task.Run(DoStopProcessingAsync); return task - this way the starting method CAN wait for the execution to finish. Works as intended now.
@Liam: Should use Task.Run and not the much more dangerous Task.Factory.StartNew.
@StephenCleary Task.run is just a wrapper for the Task.Factory.StartNew with a few switches. I don't really see why this add's much benefit? I'll add it for completeness but it's horses for courses, surely? It's also only .Net 4.5.
@Liam: Yes, but those switches are really, really important to get right. And when you don't specify them, they're wrong.
I don't target .Net 4.5 currently so we don't use this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.