c# - C# 异步编程
问题描述
我有我的 Program.cs 文件:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace AsyncTest
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
var interesting = new InterestingObject();
List<int> list;
List<int> alsoList;
list = await interesting.GenerateListAsync();
alsoList = interesting.GenerateList();
Console.WriteLine("Done! :)");
list .ForEach(xs => Console.WriteLine(xs));
alsoList.ForEach(xs => Console.WriteLine (xs));
}
}
}
这是 InterestingObject 的代码:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncTest
{
public class InterestingObject
{
public InterestingObject()
{
}
public List<int> GenerateList()
{
Console.WriteLine("Gonna generate the list!");
var list = new List<int>();
int i = 0;
while (i < 5)
{
Random random = new Random();
list.Add(random.Next());
Console.WriteLine("Generated a new int!");
VeryHeavyCalculations();
i++;
}
return list;
}
public async Task<List<int>> GenerateListAsync()
{
Console.WriteLine("Gonna generate the list async!");
var list = new List<int>();
int i = 0;
while (i < 5)
{
Random random = new Random();
list.Add(random.Next ());
Console.WriteLine("Generated a new int asyncronously!");
await Task.Run(() => VeryHeavyCalculations());
i++;
}
return list;
}
public void VeryHeavyCalculations()
{
Thread.Sleep (1000);
}
}
}
我希望list = await interesting.GenerateListAsync();
在运行时异步运行,在执行完全相同的操作时alsoList = interesting.GenerateList();
有效地将输出记录GenerateList
到我的控制台中,或者在完成时几乎立即完成。GenerateListAsync
GenerateListAsync
GenerateList
但是,查看控制台我看到我的应用程序正在运行GenerateListAsync
,然后运行GenerateList
。
我做错了,但没有足够的资源来解决这个问题。
解决方案
我希望
list = await interesting.GenerateListAsync();
在运行时异步alsoList = interesting.GenerateList();
运行,
这种期望是不正确的;的全部意义在于,在异步操作完成之前await
,它不会继续超过该点;它通过一系列技巧来做到这一点,包括异步状态机,允许在结果返回时恢复不完整的操作。但是,您可以移动您的点await
,这样它就不会导致这种感知阻塞:
List<int> list;
List<int> alsoList;
var pending = interesting.GenerateListAsync(); // no await
alsoList = interesting.GenerateList();
list = await pending; // essentially "joins" at this point... kind of
请注意,async
并行性是不同的东西;它们可以一起使用,但这不是默认情况下发生的。另请注意:并非所有代码都设计为允许并发使用,因此您不应该在不知道是否可以在特定 API 上使用并发调用的情况下做这种事情。
推荐阅读
- html - 如何为表单创建一个真实的数据库?
- java - Java Keccak-256 在零字节消息上实现不正确的哈希
- pug - (Jade/Pug) 在父块上应用 mixin
- lm - R 的 lm 函数中的残差标准误差 (RSE) 是如何计算的?
- python - 是否可以在 colab 上运行更新版本的 Python?
- java - 为什么将计算值存储在 Java 类中是不好的做法,我该如何避免呢?
- mysql - 反向迁移/删除自定义索引名称 laravel 迁移的外键
- html - 使用 Angular 将 div 动态添加到具有相同类的元素
- vb.net - 为什么我在声明我的 PFDAcroForm 时出现异常?
- windows - 尽管没有批处理文件的扩展名,但运行任意文件(例如.vbs 混合脚本文件)就好像它是批处理脚本一样