您需要同步對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();
}
}
如果您發現這種方法非常有用,你不喜歡reapeat在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));
}
或者選擇使用斯蒂芬·克利裏的AsyncLock
代替SemaphoreSlim
支持高層次的API接近lock
聲明:
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);
}
}
這是一個不同的問題,因爲這兩個線程不應該等待**相同的**任務,但是,爲了繼續,應該等待另一個線程的結束。 – nicks
你能展示你想要達到的目標嗎?也許任務的'ContinueWith()'可能是一個答案?或者'TaskCompletionSource'類? – orhtej2