C# async awaitable clarification?

人走茶凉 提交于 2019-12-12 15:16:01

问题


I've read here that :

Await examines that awaitable to see if it has already completed; if the awaitable has already completed, then the method just continues running (synchronously, just like a regular method).

What ?

Of course it won't be completed because it hasn't even started !

example :

public async Task DoSomethingAsync()
{ 
  await DoSomething();
}

Here await examines the awaitable to see if it has already completed (according to the article) , but it (DoSomething) haven't event started yet ! , so the result will always be false

It would make sence if the article was to say :

Await examines that awaitable to see if it has already completed within x ms; (timeout)

I probably missing something here..


回答1:


Consider this example:

public async Task<UserProfile> GetProfileAsync(Guid userId)
{
    // First check the cache
    UserProfile cached;
    if (profileCache.TryGetValue(userId, out cached))
    {
        return cached;
    }

    // Nope, we'll have to ask a web service to load it...
    UserProfile profile = await webService.FetchProfileAsync(userId);
    profileCache[userId] = profile;
    return profile;
}

Now imagine calling that within another async method:

public async Task<...> DoSomething(Guid userId)
{
    // First get the profile...
    UserProfile profile = await GetProfileAsync(userId);
    // Now do something more useful with it...
}

It's entirely possible that the task returned by GetProfileAsync will already have completed by the time the method returns - because of the cache. Or you could be awaiting something other than the result of an async method, of course.

So no, your claim that the awaitable won't have completed by the time you await it isn't true.

There are other reasons, too. Consider this code:

public async Task<...> DoTwoThings()
{
    // Start both tasks...
    var firstTask = DoSomethingAsync();
    var secondTask = DoSomethingElseAsync();

    var firstResult = await firstTask;
    var secondResult = await secondTask;
    // Do something with firstResult and secondResult
}

It's possible that the second task will complete before the first one - in which case by the time you await the second task, it will have completed and you can just keep going.




回答2:


await can take any Task or Task<T>, including completed tasks.

In your example, the inner DoSomething() method (that should rather be named DoSomethingAsync(), and its caller DoSomethingElseAsync()) returns a Task (or a Task<T>). That task can be a completed task fetched from somewhere else, the method is not required to start its own task.



来源:https://stackoverflow.com/questions/17380070/c-sharp-async-awaitable-clarification

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!