C# c中异步函数的差异#
我在中阅读了有关异步模式的内容,并决定采纳Jon的建议,对异步代码进行反编译,以了解实际情况。我遇到了两种情况,这让我有点困惑,为什么它们是不同的 考虑这两个功能:C# c中异步函数的差异#,c#,asynchronous,task,C#,Asynchronous,Task,我在中阅读了有关异步模式的内容,并决定采纳Jon的建议,对异步代码进行反编译,以了解实际情况。我遇到了两种情况,这让我有点困惑,为什么它们是不同的 考虑这两个功能: public static async Task<string> GetValue(){ int count = 0; count++; string g = "asdf"; var r = Task.FromResult<string> ("hello"); retu
public static async Task<string> GetValue(){
int count = 0;
count++;
string g = "asdf";
var r = Task.FromResult<string> ("hello");
return g;
}
公共静态异步任务GetValue(){
整数计数=0;
计数++;
字符串g=“asdf”;
var r=Task.FromResult(“你好”);
返回g;
}
及
公共静态异步任务GetValue(){
整数计数=0;
计数++;
字符串g=“asdf”;
var r=wait Task.FromResult(“你好”);
返回g;
}
现在我希望代码输出相同的IL,因为它们都是异步函数,所以需要一个状态机。但令我惊讶的是,C#编译器确实创建了状态机。在这两种情况下,状态机都遵循与预期完全相同的代码,除了在第一个代码块中,它实际上没有在机器中保存任何信息。在第二种情况下,它确实存储了所有变量
编译器决定不将变量保存在状态机中,并根据
await
keword公开两个不同的代码路径,这是有原因的吗?第一个应该给您一个关于不是真正异步(“将同步运行”)的警告,因为其中没有await
因此存在一个状态机,因为您将其标记为async
,可以使用wait
调用它
但是没有要保存的信息,因为在使用它的方法中没有
wait
第一个应该给你一个关于不是真正异步的警告(“…将同步运行”),因为那里没有wait
因此存在一个状态机,因为您将其标记为async
,可以使用wait
调用它
但是没有要保存的信息,因为在使用它的方法中没有
wait
我认为这种差异是由于缺少wait
操作符造成的。如果没有wait
,编译器会将您的代码视为同步代码。没有理由使用状态机
因此本质上,它创建了状态机
,正如它所期望的异步
代码一样,但实际上并没有实现任何异步
的代码。把它当作一个空容器
设置代码初始化用于表示状态的状态机
异步方法,然后使用对
状态机上的辅助MoveNext方法。这个国家机器
类型保存异步方法的状态,允许该状态
如有必要,可跨异步等待点持久化
在第二个示例中,状态机保存您的数据,因为wait
。这会触发状态机通过多个等待点
保存数据。因为另一个例子不包含wait,所以它仍然是空的。它只创建了状态机,因为您将其修饰为async
,尽管它实际上不是
这是一篇关于此事的小摘录,希望能有所帮助。我相信这种差异是由于缺少
wait
操作员造成的。如果没有wait
,编译器会将您的代码视为同步代码。没有理由使用状态机
因此本质上,它创建了状态机
,正如它所期望的异步
代码一样,但实际上并没有实现任何异步
的代码。把它当作一个空容器
设置代码初始化用于表示状态的状态机
异步方法,然后使用对
状态机上的辅助MoveNext方法。这个国家机器
类型保存异步方法的状态,允许该状态
如有必要,可跨异步等待点持久化
在第二个示例中,状态机保存您的数据,因为wait
。这会触发状态机通过多个等待点
保存数据。因为另一个例子不包含wait,所以它仍然是空的。它只创建了状态机,因为您将其修饰为async
,尽管它实际上不是
这是一个关于这个问题的小摘录,希望能有所帮助。只需要捕获
wait
表达式可见的变量:
public static async Task Method() {
int a=3;
Console.WriteLine(a);
{
int b=3;
Console.WriteLine(b);
}
await Task.FromResult(true);
}
例如,在捕获的
a
上面的代码中,b
未捕获。因此,如果不使用await
,则无需捕获任何内容。只需捕获await
表达式可见的变量:
public static async Task Method() {
int a=3;
Console.WriteLine(a);
{
int b=3;
Console.WriteLine(b);
}
await Task.FromResult(true);
}
例如,在捕获的
a
上面的代码中,b
未捕获。因此,如果不使用await
,则无需捕获任何内容。尽管没有wait,并且创建了状态机,但它却决定不跟踪任何内容,这似乎有点奇怪,我想知道为什么编译器在执行所有异步代码时会经历所有麻烦,然后忽略存储任何内容。我理解为什么状态机是为了捕获异常而存在的,但不确定为什么它会跳过保存。是否存在性能影响或其他我看不到的问题?从外部看,它仍然是异步的。为什么编译器不能实现状态机?它必须以某种方式处理等待呼叫。这也是有道理的。我只是想知道为什么会有if(!await关键字)的特殊情况不要把任何东西推到状态机上为什么还要这样branch@dbarnes因为状态机
将使用await
操作符为您的async
方法保存持久性。@dbarnes-您的代码中没有if(…)
,我没有得到您的上一个common