首页 > 解决方案 > 瞬时代码延迟?任务使用是否正确?

问题描述

所以我完成了一些编码,但我不明白发生的一些结果。我将尝试在这里编写一些与我的真实代码非常相似的乱码。如果此信息很重要:它是一个 UWP 应用。

我将使用的一种命名textBlockTextMethod()方法是带有一堆ifif-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
}

我的问题是:我的解决方案使用正确吗?有用。但这是因为我在这里很幸运,这仅在某些情况下有效,还是这是继续如何使用的常用方法Taskasync并且await

标签: c#asynchronousuwpasync-awaittask

解决方案


如果您想为受CPU 限制的工作负载释放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


推荐阅读