Я наконец изучаю асинхронное и жду ключевых слов, которые я отчасти "получаю", но все примеры, я видел вызов асинхронные методы в платформе .NET, например, этом, который звонит HttpClient.GetStringAsync()
.
То, на чем я не так ясен, - то, что продолжается в таком методе, и как я записал бы свой собственный "awaitable" метод. Действительно ли это столь же просто как обертывание кода, что я хочу выполнить асинхронно в Задаче и возврате это?
Если Вы не хотите использовать Task
, можно записать абсолютно специализированный awaitable объект. Такой объект является тем, реализовывая метод GetAwaiter ()
возврат объекта, реализовывая INotifyCompletion
, который может быть самим объектом.
реализации awaiter:
IsCompleted
, заставляют состояние GetResult ()
заставлять результат OnCompleted (Action continuation)
устанавливать делегата продолжения. awaitable объект содержит некоторый метод для фактической полезной нагрузки (например, ниже, метод Run
).
class Program {
// Need to change the declaration of Main() in order to use 'await'
static async Task Main () {
// Create a custom awaitable object
MyAwaitable awaitable = new MyAwaitable ();
// Run awaitable payload, ignore returned Task
_ = awaitable.Run ();
// Do some other tasks while awaitable is running
Console.WriteLine ("Waiting for completion...");
// Wait for completion
await awaitable;
Console.WriteLine ("The long operation is now complete. " + awaitable.GetResult());
}
}
public class MyAwaitable : INotifyCompletion {
// Fields
private Action continuation = null;
private string result = string.Empty;
// Make this class awaitable
public MyAwaitable GetAwaiter () { return this; }
// Implementation of INotifyCompletion for the self-awaiter
public bool IsCompleted { get; set; }
public string GetResult () { return result; }
public void OnCompleted (Action continuation) {
// Store continuation delegate
this.continuation = continuation;
Console.WriteLine ("Continuation set");
}
// Payload to run
public async Task Run () {
Console.WriteLine ("Computing result...");
// Wait 2 seconds
await Task.Delay (2000);
result = "The result is 10";
// Set completed
IsCompleted = true;
Console.WriteLine ("Result available");
// Continue with the continuation provided
continuation?.Invoke ();
}
}