非异步执行路径 return 同步结果能否在 "async" 方法中
Can non-asynchronous execution paths return synchronous results in an "async" method
考虑以下方法:
public async Task<string> GetNameOrDefaultAsync(string name)
{
if (name.IsNullOrDefault())
{
return await GetDefaultAsync();
}
return name;
}
当提供name
时,方法执行时不会发生等待,但该方法将正确编译。
但是,此方法会产生如下所示的构建警告:
public async Task<string> GetDefaultAsync()
{
return "foobar";
}
[CS1998] This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
为什么 GetNameOrDefaultAsync
可以 return 无需等待,并且不会导致编译器警告,但 GetDefaultAsync
必须等待才能编译?
执行以下操作会有所改进吗?:
public async Task<string> GetNameOrDefaultAsync(string name)
{
if (name.IsNullOrDefault())
{
return await GetDefaultAsync();
}
return await Task.FromResult(name);
}
这里我们将没有不await
东西的执行路径。
Why is it that GetNameOrDefault
can return without ever awaiting, and not result in a compiler warning
因为有些执行路径确实使用了 await
,并且要能够使用 await
,方法需要是 async
.
另一方面,如果 没有 路径使用 await
,async
关键字显然是多余的,因此会出现警告。
Would it be an improvement to do the following?
return await Task.FromResult(name);
不,Task.FromResult
只是将 name
包装在一个 Task
对象中,该对象处于完成状态,这意味着 await
会立即再次展开它。
这分配了一个不必要的 Task
,并没有实现。
顺便说一句,如果 name.IsNullOrDefault()
几乎总是 false
,即使用 await
是例外而不是规则,您可以通过使用 ValueTask
来减少分配:
考虑以下方法:
public async Task<string> GetNameOrDefaultAsync(string name)
{
if (name.IsNullOrDefault())
{
return await GetDefaultAsync();
}
return name;
}
当提供name
时,方法执行时不会发生等待,但该方法将正确编译。
但是,此方法会产生如下所示的构建警告:
public async Task<string> GetDefaultAsync()
{
return "foobar";
}
[CS1998] This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
为什么 GetNameOrDefaultAsync
可以 return 无需等待,并且不会导致编译器警告,但 GetDefaultAsync
必须等待才能编译?
执行以下操作会有所改进吗?:
public async Task<string> GetNameOrDefaultAsync(string name)
{
if (name.IsNullOrDefault())
{
return await GetDefaultAsync();
}
return await Task.FromResult(name);
}
这里我们将没有不await
东西的执行路径。
Why is it that
GetNameOrDefault
can return without ever awaiting, and not result in a compiler warning
因为有些执行路径确实使用了 await
,并且要能够使用 await
,方法需要是 async
.
另一方面,如果 没有 路径使用 await
,async
关键字显然是多余的,因此会出现警告。
Would it be an improvement to do the following?
return await Task.FromResult(name);
不,Task.FromResult
只是将 name
包装在一个 Task
对象中,该对象处于完成状态,这意味着 await
会立即再次展开它。
这分配了一个不必要的 Task
,并没有实现。
顺便说一句,如果 name.IsNullOrDefault()
几乎总是 false
,即使用 await
是例外而不是规则,您可以通过使用 ValueTask
来减少分配: