There is a WPF application that runs the async method. There is an infinite loop in the method that does something. You need to somehow calculate the first 10 seconds of the method and display something on the screen with the result of the method, and the method should continue to work. Such code:

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

those. Need a cut of work at 10 seconds. It does not occur to me how to do it.

  • 1) IMHO to use Thread.Sleep in asunka probably not very good, better make await Task.Delay . 2) Zdacha quite common and it can be solved in different ways, can you specify? - Vasek
  • 1) In fact, Task.Delay also wrote, but then he commented .. in general, he probably also agrees that it is better to use Task.2 in the asunka. per second. Each time an answer comes. You need to get this answer at the n-th second of the method and display it on the main form. - Denis Ivanov

2 answers 2

For example:

 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); } } 

The external code will pass its Progress<T> to the method, and will receive results from it. Instead of string you can, of course, take any T


A more accurate version (it interrupts a pause of 100 milliseconds if the time for the report has come):

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

For the case when it is necessary to give the measurement result only once, the following modification will do:

 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; } } 
  • Thank. Interesting. Only not quite understood, I do not need the time of the next stop (waitNextReportTime). It is necessary to take readings 1 time - Denis Ivanov
  • @DenisIvanov: What to do after that? Stop the calculations or count on? - VladD pm
  • As I wrote earlier, the method must continue to do what it did. 1 to 100ms to send a request .... The main method and it is the main one, it does not need to be stopped - Denis Ivanov
  • @DenisIvanov: I added the answer, at the same time I fixed the bug in the previous version of the code. - VladD

I thought towards 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 } } 
  • And this is lbk.Content = ss; Does it work? And where do you call WriteAsync() ? - Bulson pm