Ciò che è attendibile sono i ritorni Task
Task.Delay
. Ogni metodo che restituisce un Task
/Task<TResult>
è attendibile. async
è solo un dettaglio di implementazione che consente di utilizzare await
in tale metodo e l'intera macchina a stati che genera.
Più in generale, ogni cosa che ha un metodo GetAwaiter
(extension methods count as well) che restituiscono qualcosa che ha IsCompleted
, OnCompleted
e GetResult
può essere atteso.
Per esempio, Task.Yield
rendimenti YieldAwaitable
che non è una Task
e si presenta così:
public struct YieldAwaiter : ICriticalNotifyCompletion, INotifyCompletion
{
public void OnCompleted(Action continuation);
public void UnsafeOnCompleted(Action continuation);
public void GetResult();
public bool IsCompleted { get; }
}
* UnsafeOnCompleted
qui è solo un'ottimizzazione, await
avrebbe funzionato senza di essa.
È importante notare che il compilatore in questo caso (come in altri casi come GetEnumerator
per foreach
) non prevede un'interfaccia o una classe base. In pratica utilizza duck typing (ovvero "se cammina come un'anatra ...") e cerca semplicemente un metodo GetAwaiter
che restituisce qualcosa (non importa quale tipo o interfaccia o se è una classe o una struttura) che ha gli altri 3 membri (IsCompleted
, OnCompleted
e GetResult
)
Ad esempio, questo è come si può fare await "bar"
compilazione (fallirà nel runtime ovviamente):
public static Awaiter GetAwaiter(this string s)
{
throw new NotImplementedException();
}
public abstract class Awaiter : INotifyCompletion
{
public abstract bool IsCompleted { get; }
public abstract void GetResult();
public abstract void OnCompleted(Action continuation);
}
in conclusione, non è necessario necessario async
per restituire un aspetto attendibile e inoltre più Task
- metodi di restituzione nel framework .Net non lo usano e restituiscono esplicitamente un Task
.
Sono compiti che sono attesi, non le funzioni che li restituiscono. – Lee
[Domande frequenti su Async/Await] (http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/10293335.aspx): "Un" attendibile "è un tipo che espone un metodo GetAwaiter che restituisce un "cameriere" valido. Questo metodo GetAwaiter può essere un metodo di istanza (come nel caso di Task e Task), oppure può essere un metodo di estensione. " –
@ I3arnon - È stato modificato per aggiungere il tag C#, ma questa non è specificamente una domanda C# (è solo la lingua mostrata da ILSpy). Potrei usare 'Task.Delay' da VB.NET. –