Endless async and await?

2019-04-28 05:36发布

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.

4条回答
相关推荐>>
2楼-- · 2019-04-28 06:13

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.

查看更多
倾城 Initia
3楼-- · 2019-04-28 06:19

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);
}
查看更多
萌系小妹纸
4楼-- · 2019-04-28 06:26

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.

查看更多
一夜七次
5楼-- · 2019-04-28 06:33

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.

查看更多
登录 后发表回答