Я работаю с аварийным окном (Telerik WPF), который обычно отображается асинхронно (код продолжает работать, в то время как это открыто), и я хочу сделать это синхронным при помощи асинхронного/ждать.
У меня есть эта работа с TaskCompletionSource
но тот класс универсален и возвращает объект как Task<bool>
когда все, что я хочу, является плоскостью Task
без возвращаемого значения.
public Task<bool> ShowAlert(object message, string windowTitle)
{
var dialogParameters = new DialogParameters { Content = message };
var tcs = new TaskCompletionSource<bool>();
dialogParameters.Closed += (s, e) => tcs.TrySetResult(true);
RadWindow.Alert(dialogParameters);
return tcs.Task;
}
Код, который называет тот метод,
await MessageBoxService.ShowAlert("The alert text.")
Как я могу возвратить неуниверсальную Задачу, которая функционирует так же, которого я могу ждать до dialogParameters.Closed
огни события? Я понимаю, что мог просто проигнорировать bool
это возвращается в этом коде. Я ищу другое решение, чем это.
Метод может быть изменен на:
public Task ShowAlert(object message, string windowTitle)
Task<bool>
наследовался от Task
, таким образом, можно возвратиться Task<bool>
, только выставляя Task
вызывающей стороне
Редактирование:
я нашел документ Microsoft, http://www.microsoft.com/en-us/download/details.aspx?id=19957 , Stephen Toub названный 'Асинхронный шаблон На основе задач', и он имеет следующую выборку, которая рекомендует этот тот же шаблон.
нет никакого неуниверсального дубликата к TaskCompletionSource< TResult>. Однако Task< TResult> происходит из Задачи и таким образом универсального TaskCompletionSource< TResult> может использоваться для методов I/O-bound, которые просто возвращают Задачу путем использования источника с фиктивным TResult (булевская переменная является хорошим выбором по умолчанию, и если разработчик обеспокоен потребителем Задачи downcasting его к Task< TResult>, частный тип TResult может использоваться)
От @Kevin Kalitowski
я нашел документ Microsoft, http://www.microsoft.com/en-us/download/details.aspx?id=19957 , Stephen Toub названный 'Асинхронный шаблон На основе задач'
существует пример в этом документе, который я думаю, занимается проблемой, как указывает Kevin. Это - пример:
public static Task Delay(int millisecondsTimeout)
{
var tcs = new TaskCompletionSource<bool>();
new Timer(self =>
{
((IDisposable)self).Dispose();
tcs.TrySetResult(true);
}).Change(millisecondsTimeout, -1);
return tcs.Task;
}
Сначала я думал, что это не было хорошо, потому что Вы не можете непосредственно добавить "асинхронный" модификатор к методу без сообщения компиляции. Но при изменении метода немного метод скомпилирует с асинхронным/ждут:
public async static Task Delay(int millisecondsTimeout)
{
var tcs = new TaskCompletionSource<bool>();
new Timer(self =>
{
((IDisposable)self).Dispose();
tcs.TrySetResult(true);
}).Change(millisecondsTimeout, -1);
await tcs.Task;
}
Редактирование: сначала я думал, что преобладал над горбом. Но, когда я выполнил эквивалентный код в своем приложении, этот код просто заставляет приложение зависнуть, когда это добирается для ожидания tcs. Задача;. Так, я все еще полагаю, что это - серьезный недостаток дизайна в асинхронном/ждавшем c# синтаксисе.
Nito. AsyncEx реализует недженерик TaskCompletionSource
класс, кредит г-ну @StephenCleary выше.
Если Вы не хотите пропускать информацию, общий подход должен использовать TaskCompletionSource<object>
и вместе с результатом null
. Затем просто возвратите его как Task
.