Если Задача, открытая моим объектом TaskCompletionSource, никогда не может быть вызвана, как я могу выполнить вычисление результата, если и до тех пор, пока кто-то не выполнит задачу?Как реализовать ленивый источник TaskCompletion?
Например, я хочу заблокировать другие асинхронные потоки выполнения до тех пор, пока не будет выдано сообщение ManualResetEvent, используя следующую функцию WaitOneAsync. Я завершаю TaskCompleationSource в обратном вызове ThreadPool.RegisterWaitForSingleObject, который происходит, когда сигнализируется WaitHandle. Но если никто не ждет задания, то я не хочу RegisterWaitForSingleObject (и я не хочу RegisterWaitForSingleObject, если задача ожидается после сообщения WaitHandle).
Как я могу изменить WaitOneAsync так, чтобы работа по вычислению результата в RegisterWaitForSingleObject выполнялась только после того, как кто-то ждет TaskCompleationSource.Task?
Я считаю, что ответ может лежать в обычае TaskAwaiter, как описано здесь Implement AsyncManualResetEvent using Lazy<T> to determine if the task has been awaited Скотт Чемберлена, но я совсем не могу получить из его примера в моем решении ... :(
public static async Task<T> WaitOneAsync<T>(this WaitHandle waitHandle, Func<T> result) {
var tcs = new TaskCompletionSource<T>();
RegisteredWaitHandle rwh = null;
rwh = ThreadPool.RegisterWaitForSingleObject(
waitObject: waitHandle,
callBack: (s, t) => {
rwh.Unregister(null);
tcs.TrySetResult(result());
},
state: null,
millisecondsTimeOutInterval: -1,
executeOnlyOnce: true
);
return await tcs.Task;
}
@ChristopherKing Также проверьте ['AsyncFactory.FromWaitHandle'] (http://dotnetapis.com/pkg/Nito.AsyncEx/3.0.1/net45/doc/Nito.AsyncEx.AsyncFactory/FromWaitHandle (System.Threading.WaitHandle)) –