2013-06-29 231 views
3

我读过here是:C#异步等待澄清?

等待检查该awaitable,看它是否具有已经完成;如果 等待已经完成,那么方法只是继续 运行(同步,就像常规方法)。

什么?

当然,它不会完成,因为它还没有开始!

例如:

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

这里await检查awaitable,看它是否已经完成 (根据文章),但它(的DoSomething)没有事件开始呢! ,所以结果将总是false

它将使SENCE,如果文章是说:

等待检查该awaitable,看它是否具有已经完成 内x毫秒; (超时)

我可能丢失的东西在这里..

+2

你一直说这个等待的“还没有开始”,但这只是你问题中的断言/假设,而不是你在任何文档中可以指出的东西。 –

+0

@Damien_The_Unbeliever youre评论是没有帮助你知道很多....我只是读什么新阅读,它不理解。现在 - 读完这两个答案之后,事情就更加清楚了。 –

回答

13

考虑这个例子:

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; 
} 

现在想象一下调用一个在另一个异步方法:

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

这是完全有可能通过GetProfileAsync返回的任务将已经通过的时间完成方法返回 - 因为缓存。或者,当然,您可能正在等待异步方法的结果以外的其他内容。

所以不,你声称等待时间不会在你等待的时候完成是不真实的。

还有其他原因。考虑以下代码:

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 
} 

这有可能是第二个任务将在第一个之前完成 - 在这种情况下,你的时间等待第二个任务,它将完成,您只需继续前进。

+0

微软是否因为任务<..>语法而感到沮丧,他们决定把它写成糖语法?我的意思是它就像启动任务并检查结果prop ...... –

+0

@RoyiNamir:不,它确实不是。这是一个很长的路。我建议你在https://github.com/jskeet/DemoCode/tree/master/AsyncIntro处取得我的异步代码,然后尝试不用'async'来重写它。你会发现它*更*更痛苦,我向你保证。编译器正在做大量的工作来移除样板,容易出错的代码。 –

+0

Jon,在你的例子中,你使用了“从webservice_下载_” - 一个可能支持异步方法的IO操作(例如beginXXX) - 所以我们不想在IO进行时阻塞线程。 **但是**如果'DoSomething'只是一种计算长斐波那契数的方法呢?即使我们打开一个Task,它也会浪费另一个线程来进行计算。所以我问,IO操作的真正好处是什么?谢谢。 –

3

await可以采取任何TaskTask<T>包括已完成的任务

在您的例子中,内DoSomething()方法(应该而被命名为DoSomethingAsync(),其呼叫者DoSomethingElseAsync())返回一个Task(或Task<T>)。该任务可以是从其他地方获取的已完成任务,该方法不需要开始自己的任务。