sha*_*y__ 5 c# asp.net clr async-await
请考虑以下代码:
public async Task<string> GetString()
{
//Some code here...
var data = await A();
//Some more code...
return data;
}
private async Task<string> A()
{
//Some code here..
var data = await B();
//manipulating data...
return data;
}
private async Task<string> B()
{
//Some code here..
var data = await C();
//manipulating data...
return data;
}
private async Task<string> C()
{
//Some code here..
var data = await FetchFromDB();
//manipulating data...
return data;
}
private async Task<string> FetchFromDB()
{
return await SOME_HTTP_REQUEST;
}
Run Code Online (Sandbox Code Playgroud)
此代码演示了最基本的功能 - 嵌套异步方法.每种方法都会转化为状态机吗?或者编译器是否足够复杂以生成更高效的结构?在我的一些项目中,UI/WebAPI和I/O调用之间有大约20种方法 - 这是否会影响异步 - 等待开销(例如状态机)和非阻塞线程优势之间的权衡?我的意思是,例如,如果4个状态机(4个嵌套的异步方法)的开销等于50ms的阻塞I/O(就权衡而言),则20状态机将等于更长的I/O延迟( 250毫秒)?
i3a*_*non 10
await在这种情况下并不重要.每个async方法都会生成一个状态机(即使它根本没有awaits).
您可以通过此TryRoslyn示例看到它.
如果您遇到不需要状态机的情况,那么该方法实际上不需要async像这样一个例如:
private async Task<string> D()
{
var data = await FetchFromDB();
return data;
}
Run Code Online (Sandbox Code Playgroud)
您可以删除async关键字及其附带的状态机:
private Task<string> D()
{
return FetchFromDB();
}
Run Code Online (Sandbox Code Playgroud)
但是否则,你实际上需要状态机,async没有它就无法操作方法.
您应该注意,与使用保存的资源相比,开销非常小,通常可以忽略不计async-await.如果您意识到情况并非如此(通过测试),您应该只是让该操作同步.
每个方法都有一个状态机,是的.
请记住,状态机的"开销"主要是一个对象的分配(这个和几个gotos会很快),所以你执行的任何类型的"优化"都是与不创建一次类的实例相同.
至于它的成本是否大于或小于同步工作,那么你需要根据应用程序和硬件的具体情况来确定性能基准.
每个方法都会转化为状态机吗?或者编译器是否足够复杂以生成更有效的结构?
不,编译器将为每个调用生成一个状态机。编译器不会检查方法的语义调用链。它将仅在方法的基础上生成状态机。
当查看编译后的代码时,您可以清楚地看到这一点:

这是否会影响异步等待开销(例如状态机)和非阻塞线程优势之间的权衡?
您必须测试您的代码才能说出这一点。一般来说,当您需要吞吐量时,异步 IO 比较好。如果您的异步方法将被多个调用者同时调用,您将能够看到好处。如果没有,您可能看不到性能提升的任何效果。再次对您的代码进行基准测试。
| 归档时间: |
|
| 查看次数: |
2213 次 |
| 最近记录: |