我有下面一段示例代码,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);
}
它抱怨httpClient
在ExecuteAsync
完成之前不会被处理,因为它被提前声明了。如果您在内部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#会知道,在呼叫者中处理它是完全安全的。
我认为目前还没有一种只使用系统属性进行类似标记的方法。