2

In c# when you invoke the await method inside an async method, the code will be executed from the calling context to that method. What if I want to make an asynchronous call which will just continue from the same line of code directly (even if the asynchronous action did not finish yet) instead of getting back to the calling context? How can I do that?

CodeMonkey
  • 11,196
  • 30
  • 112
  • 203

3 Answers3

3

An await is, by definition, a point at which you must asynchronously wait for the task to finish before continuing the workflow. If you don't have to wait, then don't wait! There is no requirement that you await anything.

Your question is rather like asking "I have an IEnumerable<int> but I don't care what integers are in it; do I have to foreach over it?" No, you don't. If you don't care what the result is, you don't have to get a result from a sequence. If you don't care what the result of a task is, you don't have to await it.

But it is a strange thing to get a sequence and then not enumerate it, and it is a strange thing to get a task and then not care about what happens when it completes.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • So if I want to make an asynchronous call in the form of "invoke and forget", do I just call an async method and not awaiting it? If I call an async method, will it automatically be performed in the background asynchronously? – CodeMonkey Mar 07 '17 at 05:49
  • @YonatanNir: You seem to be confused. An asynchronous method is asynchronous *regardless* of whether it is awaited. But that doesn't mean that it runs on a background thread! – Eric Lippert Mar 07 '17 at 05:59
  • @YonatanNir: Let's make an analogy. People are threads. You are doing your taxes. You realize that you need a number from your bank, so you go to your bank's web site, but it is running slowly. So while you are waiting for the web site to come back up you go make a sandwich and then never actually go back to the web site or finish your taxes. Now, **did you have to hire a worker to watch your computer for you**? No, of course not. There's no "background worker" in this workflow. – Eric Lippert Mar 07 '17 at 06:01
  • @YonatanNir: now, had you *awaited* the web site returning a result, then you would have gone and made a sandwich, and maybe the web site comes back with the result while you're eating, and when you're done you go back to the web site, get the number, and finish your taxes. Again, **did you have to hire a worker to watch the web site for you?** Of course not. **Asynchronous operations don't necessarily run on worker threads**. – Eric Lippert Mar 07 '17 at 06:03
  • @YonatanNir: But the important thing to realize is that *await does nothing* to make an operation asynchronous. The operation has to *already* be asynchronous. Await just means "do something else if this operation isn't complete yet, and come back here when it is*. Is the operation running in the background? Maybe. Maybe not. Who knows? All you know is that it is an asynchronous operation. It might be an asynchronous operation that will complete *in the future on this thread*. – Eric Lippert Mar 07 '17 at 06:05
  • @YonatanNir: Think of await as like foreach. Does foreach make something a sequence? Of course not. foreach *extracts values from sequences*. Does await make something asynchronous? Of course not. Await *extracts values from asynchronous operations when the operation completes*. – Eric Lippert Mar 07 '17 at 06:08
  • All I want to know is how to make an invoke and forget call which will run in the background. You're saying async and await are not like that and I get it, but I'm asking how I DO that kind of thing. Not asking if async await is something that does it.. I'm asking how can I actually make an action which will run in the background and the code will simply continue to the next line. – CodeMonkey Mar 07 '17 at 06:14
3

What if I want to make an asynchronous call which will just continue from the same line of code directly (even if the asynchronous action did not finish yet) instead of getting back to the calling context? How can I do that?

The easiest way, which works whether Something is synchronous or asynchronous:

var _ = Task.Run(() => Something());

But, as Eric Lippert stated:

it is a strange thing to get a task and then not care about what happens when it completes.

Or, as I like to put it: fire-and-forget is almost never what you really want. To "forget" means:

  1. You don't care when it completes.
  2. You don't care whether it completes. E.g., if your app exits (or app pool is recycled if on ASP.NET), then your background work is just lost.
  3. You don't care whether it completes successfully. E.g., if your work throws an exception, you want to silently swallow that exception.

In real-world code, this scenario is extremely rare.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

If you want to start the async method and continue inside the function you can do something like Task<string> getStringTask = asyncMethodThatReturnsString();. Then continue until you want to wait for the async task to finish at which point you would call string output = await getStringTask;.

WereGoingOcean
  • 98
  • 1
  • 10
  • But what if I don't actually need to wait? Just launch and forget kind of thing – CodeMonkey Mar 07 '17 at 05:27
  • Are you saying you never want to wait for the async method to return? – WereGoingOcean Mar 07 '17 at 05:31
  • I was referring more to a pure asynchronous call and not just a method with the async keyword – CodeMonkey Mar 07 '17 at 05:33
  • If I'm invoking a method with the async key word but not awaiting it, will it just run asynchronously in the background? – CodeMonkey Mar 07 '17 at 05:36
  • 1
    [This blog post](http://blog.stephencleary.com/2012/02/async-and-await.html) might help. I found it on [a question about using async without await.](http://stackoverflow.com/questions/17805887/can-i-use-async-without-await-in-c) – WereGoingOcean Mar 07 '17 at 05:41
  • @YonatanNir: That is a strange question which makes me think that you do not understand how asynchrony works. There is not any "background" necessarily. Do you believe the falsehood that await *causes* asynchrony? It does not. Await *suspends a workflow until an asynchronous operation completes*. It does not *make its operand asynchronous*. The operation has to *already* be asynchronous. – Eric Lippert Mar 07 '17 at 05:41