c# - 如果 Task.run 可以实现相同的效果,为什么还要使用异步等待
问题描述
以下两种方法的行为方式是否相同?它们的工作方式是否存在内部差异?一旦延迟结束,这两种方法都会释放 UI 线程并继续执行。
public async Task DoSomethingAsync()
{
Console.WriteLine("Test Async start");
//Any long running operation
await Task.Delay(5000);
Console.WriteLine("Test Async end");
}
public void TestTask()
{
Console.WriteLine("Test Task start");
Task.Run(() =>
{
//Any long running operation
Thread.Sleep(10000);
}
).ContinueWith((prevTask) =>
{
Console.WriteLine("Test Task end");
});
}
**output**:
Test Async start
Test Task start
Test Async end
Test Task end
解决方案
async 和 await 关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不在其自己的线程上运行。该方法在当前同步上下文上运行,并且仅在该方法处于活动状态时才使用线程上的时间。
您不需要 System.Threading 的任务。下面的代码确实是因为 CancellationToken。
一个区别是 Task 您可以访问主(UI)线程上的属性。
请参阅数量。您甚至可以写入主线程,但可能不是一个好习惯。
async Task<int> TaskDelayAsync(CancellationToken ct, IProgress<int> progress)
{
Debug.WriteLine(Quantity);
int i = 0;
while (true)
{
i++;
//Debug.WriteLine(i);
progress.Report(i);
ct.ThrowIfCancellationRequested();
await Task.Delay(500);
}
return i;
}
推荐阅读
- c# - 如何获取一维条码图像的原始数据?
- java - 尝试使用与标题关联的正则表达式来获取多行 HTML
- java - JDK11 javac类型推断错误信息解读
- windows - RemoveRegistryKey 不删除注册表项
- python - Python中的np.trapz计算
- c++ - 为什么使用“constexpr”会在代码块中给出主要表达式错误
- javascript - 如何在 JavaScript(es6)中过滤另一个对象数组中的对象数组?
- reactjs - 使用带有多个选项的 Material UI Autocomplete 时如何在保持状态的同时防止重新渲染?
- r - JAGS 中的解析问题
- node.js - 如何将主代码与 index.js 电子分开?