I have analyzed my project using Microsoft.Visual Studio.Threading.Analyzers.
I get the following warning on the task
:
Link: https://github.com/Microsoft/vs-threading/blob/main/doc/analyzers/VSTHRD003.md
I don’t quite understand, does this have something to do with the synchronization context? I use ASP.NET Core, as far as I understand it is not there.
<code>public async Task<WaitForValueResponse> WaitForValueAsync(string key, int millisecondsWait, CancellationToken cancellationToken)
{
Subscribe(key, out string subscriberKey, out Task<string> task);
if (_storageValues.TryGetValue(key, out var storageValue))
{
Unsubscribe(subscriberKey);
return new WaitForValueResponse(Value: storageValue.Value);
}
var completionSource = new TaskCompletionSource<bool>();
await using (cancellationToken.Register(() => completionSource.TrySetCanceled()))
{
var completedTask = await Task.WhenAny(task, completionSource.Task, Task.Delay(millisecondsWait, cancellationToken));
Unsubscribe(subscriberKey);
if (completedTask == task)
{
return new WaitForValueResponse(Value: await task);
}
else if (completedTask == completionSource.Task)
{
cancellationToken.ThrowIfCancellationRequested();
}
else
{
return new WaitForValueResponse(Success: false, ErrorMessage: "The waiting time has expired.");
}
}
throw new InvalidOperationException("The code has entered an invalid state.");
}
</code>
<code>public async Task<WaitForValueResponse> WaitForValueAsync(string key, int millisecondsWait, CancellationToken cancellationToken)
{
Subscribe(key, out string subscriberKey, out Task<string> task);
if (_storageValues.TryGetValue(key, out var storageValue))
{
Unsubscribe(subscriberKey);
return new WaitForValueResponse(Value: storageValue.Value);
}
var completionSource = new TaskCompletionSource<bool>();
await using (cancellationToken.Register(() => completionSource.TrySetCanceled()))
{
var completedTask = await Task.WhenAny(task, completionSource.Task, Task.Delay(millisecondsWait, cancellationToken));
Unsubscribe(subscriberKey);
if (completedTask == task)
{
return new WaitForValueResponse(Value: await task);
}
else if (completedTask == completionSource.Task)
{
cancellationToken.ThrowIfCancellationRequested();
}
else
{
return new WaitForValueResponse(Success: false, ErrorMessage: "The waiting time has expired.");
}
}
throw new InvalidOperationException("The code has entered an invalid state.");
}
</code>
public async Task<WaitForValueResponse> WaitForValueAsync(string key, int millisecondsWait, CancellationToken cancellationToken)
{
Subscribe(key, out string subscriberKey, out Task<string> task);
if (_storageValues.TryGetValue(key, out var storageValue))
{
Unsubscribe(subscriberKey);
return new WaitForValueResponse(Value: storageValue.Value);
}
var completionSource = new TaskCompletionSource<bool>();
await using (cancellationToken.Register(() => completionSource.TrySetCanceled()))
{
var completedTask = await Task.WhenAny(task, completionSource.Task, Task.Delay(millisecondsWait, cancellationToken));
Unsubscribe(subscriberKey);
if (completedTask == task)
{
return new WaitForValueResponse(Value: await task);
}
else if (completedTask == completionSource.Task)
{
cancellationToken.ThrowIfCancellationRequested();
}
else
{
return new WaitForValueResponse(Success: false, ErrorMessage: "The waiting time has expired.");
}
}
throw new InvalidOperationException("The code has entered an invalid state.");
}
How do I make this code valid? I tried to write this through JoinableTaskFactory, but the warning doesn’t work.
<code>string result;
JoinableTask joinableTask = joinableTaskFactory.RunAsync(async () =>
{
result = await task;
});
</code>
<code>string result;
JoinableTask joinableTask = joinableTaskFactory.RunAsync(async () =>
{
result = await task;
});
</code>
string result;
JoinableTask joinableTask = joinableTaskFactory.RunAsync(async () =>
{
result = await task;
});
A similar warning occurs in my middleware on the await t
:
<code>private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
{
try
{
var response = await t;
return response;
}
catch (RpcException e)
{
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
return default;
}
}
</code>
<code>private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
{
try
{
var response = await t;
return response;
}
catch (RpcException e)
{
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
return default;
}
}
</code>
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
{
try
{
var response = await t;
return response;
}
catch (RpcException e)
{
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
return default;
}
}