我是ASP.NET Core和C#的新手,一般来自Java世界,我对async/await关键字如何工作有点困惑:本文解释了如果一个方法被标记为异步,则意味着
"此方法包含涉及等待异步操作的控制流,因此将由编译器重写为连续传递样式,以确保异步操作可以在正确的位置恢复此方法." 异步方法的重点在于它当前线程尽可能多
所以我认为在异步方法和在字节码/虚拟机级别上实现的同一线程上运行的调用者之间传递控制是一种非常酷的方式.我的意思是我期望下面的代码
public static void Main(string[] args)
{
int delay = 10;
var task = doSthAsync(delay);
System.Console.WriteLine("main 1: " + Thread.CurrentThread.ManagedThreadId);
// some synchronous processing longer than delay:
Thread.Sleep(2 * delay)
System.Console.WriteLine("main 2: " + Thread.CurrentThread.ManagedThreadId);
task.Wait();
}
public static async Task<String> doSthAsync(int delay)
{
System.Console.WriteLine("async 1: " + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(delay);
System.Console.WriteLine("async 2: " + Thread.CurrentThread.ManagedThreadId);
return "done";
}
Run Code Online (Sandbox Code Playgroud)
会写的
async 1: 1 main 1: 1 main 2: 1 async 2: 1 …
下面的方法编译没有问题:
static Stream<Optional<? extends Number>> getNumbers(Stream<Number> numbers) {
return numbers.map(Optional::of);
}
Run Code Online (Sandbox Code Playgroud)
但如果我像这样添加一个简单的过滤:
static Stream<Optional<? extends Number>> getNumbers2(Stream<Number> numbers) {
return numbers.map(Optional::of).filter(number -> true);
}
Run Code Online (Sandbox Code Playgroud)
它会生成以下错误:
不兼容的类型:
java.util.stream.Stream<java.util.Optional<java.lang.Number>> 无法转换为
java.util.stream.Stream<java.util.Optional<? 扩展 java.lang.Number>>
在 openJdk-11 和 openJdk-17 上进行了测试。
我希望它们都做同样的事情(要么都编译正常,要么都生成相同的编译错误),所以我真的对此感到困惑:这里的一般规则是什么解释了为什么第一种方法编译正常而第二种方法编译正常才不是?谢谢!