代码之家  ›  专栏  ›  技术社区  ›  nicks

可以在不同的线程上等待任务完成吗?[副本]

  •  -1
  • nicks  · 技术社区  · 7 年前

    我的意思是,假设我们有一个异步方法 Task<string> CalculateSha256(string s) 连续地 至于并发执行,线程#1和#2彼此都不知道吗?例如,我有一个控制器,

    public async Task<string> Get(string value)
    {
        return await CalculateSha256(value);
    }
    

    1 回复  |  直到 7 年前
        1
  •  4
  •   YuvShap    7 年前

    您需要同步对CalculateSha256方法的访问,一次只有一个线程执行它。
    自从 lock does not play nicely with async 您可以使用 SemaphoreSlim

    private static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
    

    和使用 WaitAsync 方法(并且在完成时不要忘记释放它,使用finally block):

    public async Task<string> Get(string value)
    {
        await _semaphoreSlim.WaitAsync();
        try
        {
            return await CalculateSha256(value);
        }
        finally
        { 
            _semaphoreSlim.Release();
        }
    }
    

    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 而不是 它支持更接近 声明:

    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);
        }
    }