Есть WPF приложение, в котором запускается async метод. В методе есть бесконечный цикл, который что-то делает. Нужно каким то образом посчитать первые 10 секунд работы метода и вывести что-то на экран с результатом работы метода, при этом метод должен продолжать работать. Такой код:
private async Task WriteAsync()
{
while (true)
{
что-то делаем...и этот результат работы на n-ой секунде передать в другое место
System.Threading.Thread.Sleep(100); // ждем 100 мс и повторяем
}
}
т.е. нужен срез работы на 10 секунде. В голову не приходит как это сделать
Например, так:
async Task WriteAsync(IProgress<string> progress)
{
DateTime nextReportTime = DateTime.Now + TimeSpan.FromSeconds(10);
while (true)
{
if (DateTime.Now > nextReportTime)
{
progress.Report(тут ваши данные);
nextReportTime = DateTime.Now + TimeSpan.FromSeconds(10);
}
// что-то делаем...
await Task.Delay(100);
}
}
Внешний код передаст в метод свой Progress<T>, и будет получать из него результаты. Вместо string можно, понятно, брать любой T.
Более точная версия (она прерывает паузу в 100 миллисекунд, если пришло время отчёта):
async Task WriteAsync(IProgress<string> progress)
{
Task waitNextReportTime = Task.Delay(TimeSpan.FromSeconds(10));
while (true)
{
// что-то делаем...
var pauseTask = Task.Delay(100);
await Task.WhenAny(waitNextReportTime, pauseTask);
if (waitNextReportTime.IsCompleted)
{
progress.Report(тут ваши данные);
waitNextReportTime = Task.Delay(TimeSpan.FromSeconds(10));
}
await pauseTask;
}
}
Для случая, когда нужно выдать результат измерений лишь один раз, подойдёт такая модификация:
async Task WriteAsync(IProgress<string> progress)
{
Task waitReportTime = Task.Delay(TimeSpan.FromSeconds(10));
while (true)
{
// что-то делаем...
var pauseTask = Task.Delay(100);
if (waitReportTime != null)
{
await Task.WhenAny(waitReportTime, pauseTask);
if (waitReportTime.IsCompleted)
{
waitReportTime = null;
progress.Report(тут ваши данные);
}
}
await pauseTask;
}
}
Я подумал в сторону DispatcherTimer
int l=10; // 10 секунд;
t2 = new DispatcherTimer();
t2.Interval = new TimeSpan(0, 0, 1);
t2.IsEnabled = true;
t2.Tick += (o1, ee1) => { GetValuesCom(); };
private void GetValuesCom()
{
if (l>0)
{
l = l - 1;
}
else
{
t2.Stop();
lbk.Content = ss; //ss - переменная которая фигурирует в WriteAsync
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости