причина, по которой я сделал это, потому что мне нужно создать задачу в определенный момент времени, но запустить ее позже
Подходящим инструментом в этом случае является Func<Task>
, а не конструктор Task
. Конструктор Task
никогда и никогда не должен использоваться .
В этом случае ваши выходные данные не соответствуют желаемым, поскольку конструктор Task
не понимает делегатов async
. Таким образом, делегат async
, передаваемый конструктору Task
, обрабатывается как async void
, что делает ожидание его невозможным.
Исправление заключается в использовании async
-осведомленных инструментов. В этом случае асинхронно-совместимый делегат . Поскольку объект Task
не существует до тех пор, пока не сработает событие таймера, вам также необходимо передать этот объект другому методу в виде «сигнала», что несколько неудобно. Большая часть реального кода не нуждается в этом:
private static Func<Task> _func;
private static TaskCompletionSource<Task> _taskSignal = new TaskCompletionSource<Task>();
private static async Task Call()
{
_func = Pause;
var timer = new Timer();
timer.Interval = 10000;
timer.Enabled = true;
timer.AutoReset = false;
timer.Elapsed += Timer_Elapsed;
Console.WriteLine("job waiting");
var task = await _taskSignal.Task; // Get the Task instance representing Pause
await task; // Wait for Pause to finish
Console.WriteLine("job done");
Console.ReadKey();
}
public static async Task Pause()
{
Console.WriteLine("Delay started");
await Task.Delay(10000);
Console.WriteLine("Delay ended");
}
private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Console.WriteLine("job starting");
var task = _func(); // Start Pause running
_taskSignal.TrySetResult(task); // Pass the Pause task back to Main
}