Мгновенный код задерживается?Правильно ли используется задание? - PullRequest
0 голосов
/ 06 марта 2019

Итак, я закончил некоторое кодирование, но я не понял некоторых результатов, которые произошли.Я постараюсь написать здесь какой-то бредовый код, который очень похож на мой реальный код.Если эта информация важна: это приложение UWP.

Один метод, который я буду использовать, будет называться textBlockTextMethod() - это метод с набором операторов if и if-else, которые всегда заканчиваютсядавая textBlock.Text новый текст (в этом примере пусть он всегда будет "End").

Итак, сначала давайте посмотрим, как мой код выглядел первым:

private void DoSomething()
{
textBlock.Text = "Start";
aIntVal = aMethod(); //aIntVal being a `int` variable
textBlockTextMethod();
}

private int aMethod()
{
int anotherIntVal = 0;


 for(int i = 0; i < number; i++)
  {
  anotherIntVal += randomNum; // randomNum being a random 'int' value
  }

return anotherIntVal
}

Чтоя ожидал от этого?Я хотел, чтобы у textBlock.Text был текст "Start", чтобы я мог визуально видеть Start в приложении UWP.Тогда aIntVal должен получить значение int от aMethod().Для aMethod() требуется около 2-3 секунд, и после этого textBlock.Text должно иметь другое значение из textBlockTextMethod.

Здесь произошло то, что TextBlock не будет отображать текст Start,Приложение UWP зависло бы на 2 секунды, а затем я увидел бы End в приложении UWP, которое было установлено в textBlockTextMethod().

Почему так, что я не мог видеть Start? Я, хотя это было бы видно во время заморозки.Но похоже, что aMethod вызывается до того, как Start установлено на textBlock.Text (или, скорее, Start никогда не настроено на textBlock.Text)

Затем я попробовал что-то другое.Это моя вторая попытка использования кода:

private async void DoSomething()
{
Task<string> aTask = taskMethod()
textBlock.Text = await aTask;
aIntVal = aMethod();
textBlockTextMethod();
}

private async Task<string> taskMethod()
{
textBlock.Text = "Start";
await Task.Delay(1);
return "";
}

private int aMethod()
{
int anotherIntVal = 0;


 for(int i = 0; i < number; i++)
  {
  anotherIntVal += randomNum();
  }

return anotherIntVal
}

Это позволило мне увидеть Start в приложении UWP во время остановки.Но это не было очень последовательным.Большую часть времени я мог видеть Start.Но несколько раз у меня была та же проблема, что и раньше, но Start не показывалось.

Я заметил, что изменение Task.Delay(1) на Task.Delay(100) покажет мне Start непротиворечивым. Почему это так?

Теперь это третья попытка моего кода, который я сейчас использую:

private async void DoSomething()
{
textBlock.Text = "Start";
aIntVal = await aMethod();
textBlockTextMethod();
}

private async Task<int> aMethod()
{
int anotherIntVal = 0;

await Task.Run(() =>
 {
 for(int i = 0; i < number; i++)
  {
  anotherIntVal += randomNum();
  }
 });
return anotherIntVal
}

Мой вопрос здесь: Является ли мойРешение используется правильно? Работает.Но это потому, что мне просто повезло, и это работает только в некоторых случаях, или это обычный способ использования Task, async и await?

1 Ответ

3 голосов
/ 06 марта 2019

Если вы хотите высвободить UI для ЦП рабочей нагрузки, вы можете сделать что-то вроде этого

// async task
private async void ButtonClick()
{
   // update the text box
   textBlock.Text = "Start";

   // if we have to wrap some CPU work, dont do it in the implementation
   // use task run to call it.
   // So... lets do something on the thread pool
   // await the results, giving back the ui thread
   var aIntVal = await Task.Run(() => aMethod()); 
   // continue back on the UI thread and update the text box again
   textBlock.Text = aIntVal;
}

// Vanilla method to do stuff
private int aMethod()
{
   for (int i = 0; i < number; i++)
       // awesome calculations here
   return anotherIntVal;
}

Дополнительные ресурсы

Читать все Стивен Клири

Начните здесь Примеры этикета Task.Run: не используйте Task.Run в реализации

...