捕获的变量在外部作用域中处理



我有下面一段示例代码,resharper向其抱怨"捕获的变量被置于"外部范围"中;。我在这里没有任何问题,因为正在等待调用未命名lambda的ExecuteAsync,因此不会在作用域之外使用httpClient。这是假阳性吗?

private static async Task MyTestFunction(IHttpClientFactory httpClientFactory) {
string baseUrl = "http://localhost:8000";
using var httpClient = httpClientFactory.CreateClient();
try {
await ExecuteAsync(
async () => {
try {
await httpClient.GetAsync(new Uri(baseUrl)).ConfigureAwait(false);
} catch (Exception ex) {
Console.WriteLine(ex);
throw;
}
}).ConfigureAwait(false);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
throw;
}
}
private static async Task ExecuteAsync(Func<Task> func) {
await func().ConfigureAwait(false);
}

它抱怨httpClientExecuteAsync完成之前不会被处理,因为它被提前声明了。如果您在内部try语句中声明它,则可以提前处理它。

注意:这可能对性能没有什么好处,如果有的话,ReSharper会为它标记的东西坚持一套严格的规则。

将您的基本url设置为const变量也是一个好主意,因为它永远不会更改。

private const string BaseUrl = "http://localhost:8000";
private static async Task MyTestFunction(IHttpClientFactory httpClientFactory) 
{
try {
await ExecuteAsync(
async () => {
try {
using var httpClient = httpClientFactory.CreateClient();
await httpClient.GetAsync(new Uri(BaseUrl)).ConfigureAwait(false);
} catch (Exception ex) {
Console.WriteLine(ex);
throw;
}
}).ConfigureAwait(false);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
throw;
}
}
private static async Task ExecuteAsync(Func<Task> func) {
await func().ConfigureAwait(false);
}

它抱怨,因为ExecuteAsync的合约中没有任何内容要求它只使用在自己执行过程中接收的函数(例如,它可以将其存储在LastExecutedFunction字段中(。

如果使用JetBrains注释,请将func参数标记为[InstantHandle],以明确记录该方法将立即使用该参数。Rider/R#会知道,在呼叫者中处理它是完全安全的。

我认为目前还没有一种只使用系统属性进行类似标记的方法。

最新更新