8

I don´t understand something about async/await:

It is mandatory that an async method must have an await call inside... But if there is an await it is because it is calling another async method, right? So it seems to be an endless chain of async methods with awaits inside calling another async methods.

So is it possible to create a "first" async method, not calling any other async methods inside. Just create an async method because that method does a lot of work that could slow down the system.

2
  • 6
    "It is mandatory that an async method must have an await call inside..." No, it's the other way around: if you're using await inside a method, that method must be marked async. You can mark it async and not use an await (but that's usually incorrect) Commented Jul 2, 2014 at 12:06
  • @Dennis_E It's not required that an async method have an await, but there is almost never a sensible reason to do so, as the async would just be a lie. Commented Jul 2, 2014 at 19:34

4 Answers 4

6

First, some clarifications

A method doesn't need an await to be async, it's the other way around. You can only use await in an async method. You may have a method that returns a Task without it being marked as async. More here.

Your actual question

IIUC, is about "The Root Of All Async". So, yes, it is possible to create a "first" async method. It's simply a method that returns a Task (or Task<T>).

There are two types of these tasks: A Delegate Task and a Promise Task.

  1. A Delegate Task is fired by Task.Run (most times. Task.StartNew and new Task(() => {}); are other options) and it has code to run. This is mostly used for offloading work.
  2. A Promise Task is a Task that doesn't actually execute any code, it's only a mechanism to a. Wait to be notified upon completion by the Task. b. Signaling completion using the Task. This is done with TaskCompletionSource and is mostly used for inherently asynchronous operations (but also for async synchronization objects) for example:

.

private static Task DoAsync() { var tcs = new TaskCompletionSource<int>(); new Thread(() => { Thread.Sleep(1000); tcs.SetResult(5); }).Start(); return tcs.Task; } 

These tools allow you to create those "roots", but unless you implement an I/O library (like .Net's DNS class) or a synchronization object (like SemaphoreSlim) yourself, you would rarely use them.

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

1 Comment

Thanks, your answer let me search more for TaskCompletionSource. To better understand it and when to use it, here is a StackOverflow link. It takes you to this code example.
2

The purpose of the async keyword is to simply allow the use of await inside the method, you don't have to call another async method internally e.g.

public async void WaitForSomething() { await Task.Delay(1000); } 

3 Comments

Right. A method being async is just an implementation detail. The thing you're awaiting is just an object (usually a Task) that implements the 'async pattern'.
Hmm 2 downvotes, care to elaborate? As far as I am aware my answer is technically accurate.
@James Assuming the OP isn't asking about the async keyword, but about asynchronous awaitable method calls then "is it possible to create a "first" async method, not calling any other async methods inside?" is about how to implement Task.Delay, not how to call it.
1

Sure, there are indeed ways of creating a Task besides using an async method.

  • You can use the task constructor (although unless you have a particularly compelling reason to create a task that represents the execution of a delegate that you use before the delegate actually starts executing, you should really avoid doing this. Just use the next option.

  • You can use an existing method of Task to create tasks, such as Task.Run to represent the execution of a delegate in another thread, Task.WhenAll to represent the completion of a series of other tasks, Task.FromAsync to create a task based on a different pattern of asynchronous programming, etc.

  • You can use a TaskCompletionSource to create a task that you complete whenever you want, allowing you to turn any inherently asynchronous behavior into a Task. That inherently asynchronous operation could be an event firing, a callback method being called, etc.

Comments

0

If you have a very intensive method which does a lot of work that could slow down the system, you can call it like this.

public async void CallerAsyncMethod() { var taskResult = Task.Factory.StartNew(() => IntensiveMethod()); await taskResult; } 

Here IntensiveMethod is not an async method.

Hope it helps.

7 Comments

this does not answer the question at all
@Morgoz needed to call a non-async method from an async method. This is the way it can be achieved. Please let me know where I am mistaken.
"It is mandatory that an async method must have an await call inside... " .... yours have one right at the end - so it's no counterexample (but the downvote is not from me - I was tempted though)
@CarstenKönig Well, its not for the downvote though... Learning is more important. I much emphasized on calling a non-async method.
yes but he asked if it's even possible to have one without any await and here your answer does not help at all
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.