Задачи C # с отчетом о проделанной работе и возвращаемым значением, не сообщающим о прогрессе - PullRequest
0 голосов
/ 31 октября 2018

Я пытаюсь запустить задачу в методе, и метод возвращает значение. Причина, по которой я использую задачу, заключается в том, что мне нужны отчеты о прогрессе

Это была моя оригинальная стратегия

   private async void CallLongRunningTask()
   {
       string fileName = "TestFN";
       Progress<string> progress = new Progress<string>();
       progress.ProgressChanged += (_, newText) => lbl.Text=newText;
       bool retVal = await Task.Run(() => LongRunningTask(fileName, progress));
       Task.WaitAll();
       // do some other stuff    

   }

   public bool LongRunningTask(string fn, IProgress<string> progress)
   {
       // long running task with progress report
         while (i < 100000000)
        {
            i++;
            if (i % 10000 == 0)
            {
                progress.Report("Processing "+i.ToString());
            }
        }
        return true;
   }

Как и ожидалось, он прошел через WaitAll, вернулся к предыдущему методу.

Итак, я попробовал это:

got rid of async in the signature

bool retVal = Task.Run(() => LongRunningTask(fileName, progress));
bool retVal = Task.Run(async () => LongRunningTask(fileName, progress));

В обоих случаях я потерял свой прогресс.

Итак, я попытался изменить свою вызывающую программу:

   Task.Run(() => CallLongRunningTask()).Wait();

Это нарушило мои отчеты о прогрессе, потому что мои отчеты о прогрессе обновили метку в форме, так что произошло некоторое перекрестное заражение.

Я прочитал и перепробовал все похожие похожие проблемы / решения. Это кажется таким простым, но я явно что-то упускаю. Кажется, что весь Task () и асинхронная вещь находятся на уровне абстракции, которую я не могу понять независимо от того, сколько раз я читал книгу Стивена Клири.

Буду очень признателен за любые мысли, идеи или помощь!

1 Ответ

0 голосов
/ 31 октября 2018

Нет необходимости в WaitAll, как уже упоминалось.

private async Task CallLongRunningTask() {
    string fileName = "TestFN";
    Progress<string> progress = new Progress<string>();
    progress.ProgressChanged += (_, newText) => lbl.Text=newText;

    //waiting here for long running task to finish
    bool retVal = await Task.Run(() => LongRunningTask(fileName, progress));

    // do some other stuff after waiting
}

асинхронное ожидание распространяется до самого конца. Вам нужно дождаться всего, включая вызывающий метод.

await CallLongRunningTask();

и т. Д.

При вызове из обработчика событий это единственное исключение, где можно использовать async void

private async void OnSomeHandler(object sender, EventArgs args) {
    //...

    await CallLongRunningTask();

    //...
}

Ссылка Async / Await - Лучшие практики в асинхронном программировании

...