WPF. Отсчитать время в Async методе

218
26 марта 2018, 22:11

Есть WPF приложение, в котором запускается async метод. В методе есть бесконечный цикл, который что-то делает. Нужно каким то образом посчитать первые 10 секунд работы метода и вывести что-то на экран с результатом работы метода, при этом метод должен продолжать работать. Такой код:

private async Task WriteAsync()
{                     
    while (true)
    {
        что-то делаем...и этот результат работы на n-ой секунде передать в другое место               
        System.Threading.Thread.Sleep(100); // ждем 100 мс и повторяем                
    }
}

т.е. нужен срез работы на 10 секунде. В голову не приходит как это сделать

Answer 1

Например, так:

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;
    }
}
Answer 2

Я подумал в сторону 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
  }
}
READ ALSO
Отображение данных с помощью Partial View

Отображение данных с помощью Partial View

Есть 2 модели, пользователи и программы (в этом вопросе есть описание моделей)Я хочу отобразить в таблицах все программы из бд, и следом всех...

209
Поиск по году в БД

Поиск по году в БД

Есть таблица со столбцом "Дата" формата 2018-03 в sql serverВвел в textBox год 2018 Как вывести в DataGridView все записи c таким годом?

215
Крутящееся колесо SVG

Крутящееся колесо SVG

Необходимо сделать крутящийся круг из секторов

275
Проблема с дополенеием Cannot set property &#39;onclick&#39; of null

Проблема с дополенеием Cannot set property 'onclick' of null

Разрабатываю расширения для Chrome (Opera and Yandex)Появилась ошибка в консоли "popup

254