c# – 将锁迁移到TPL

在正常的C#中我们写

int DoSomething(){/*...*/)};

lock(mutex)
{
    return DoSomething();
}

确保在所有情况下释放互斥锁.

但如果DoSomething的签名变为

Task<int> DoSomeThingAsync(){/*...*/};

是否有以下代码

return Task.Factory.StartNew(() =>
{
    Monitor.Enter(mutex);
    return DoSomethingAsync();
}).Unwrap().ContinueWith(t =>
{
    Monitor.Exit(mutex);
    return t;
}).Unwrap();

做类似的事情?是否保证在输入时释放互斥锁?有没有更简单的方法呢? (我无法使用async关键字,所以请继续考虑TPL)

你不能以这种方式使用Monitor,因为Monitor是线程仿射的,在你的情况下,任务和继续可以在不同的线程上运行.

要使用的适当同步机制是将SemaphoreSlim(不是线程仿射)设置为1:

public SemaphoreSlim _semaphore = new SemaphoreSlim(1,1);

_semaphore.Wait();
return DoSomethingAsync().ContinueWith(t =>
{
    _semaphore.Release();
    return t.Result;
});

只要您不使用TaskContinuationOptions之一(例如OnlyOnFaulted或OnlyOnCanceled),继续将始终在任务完成后运行,因此保证信号量被释放.

相关文章
相关标签/搜索