您需要同步对CalculateSha256方法的访问,该方法一次只有一个线程会执行。
由于lock 声明does not play nicely with async 你可以使用SemaphoreSlim 类。
只需将其作为静态字段添加到您的控制器:
private static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
并在您的操作中使用WaitAsync 方法(完成后不要忘记释放它,使用 finally 块):
public async Task<string> Get(string value)
{
await _semaphoreSlim.WaitAsync();
try
{
return await CalculateSha256(value);
}
finally
{
_semaphoreSlim.Release();
}
}
如果您发现这种方法很有用并且您不喜欢重复 try finally 块,您可以创建一个带有受保护的通用帮助器的基本控制器类:
protected async Task<T> GetConsecutively(Func<Task<T>> taskFactory)
{
await _semaphoreSlim.WaitAsync();
try
{
return await taskFactory();
}
finally
{
_semaphoreSlim.Release();
}
}
并修改 Get 方法以将 lambda 表达式传递给它:
public async Task<string> Get(string value)
{
return await GetConsecutively(() => CalculateSha256(value));
}
或者使用 Stephen Cleary 的 AsyncLock 代替 SemaphoreSlim,它支持更接近 lock 语句的高级 API:
private static readonly AsyncLock _asyncLock = new AsyncLock();
public async Task<string> Get(string value)
{
//Notice the use of using block
//instead of try and finally
using(await _asyncLock.LockAsync())
{
return await CalculateSha256(value);
}
}