C# 将锁迁移到TPL

C# 将锁迁移到TPL,c#,.net,synchronization,task-parallel-library,C#,.net,Synchronization,Task Parallel Library,在正常情况下,我们写 确保在所有情况下释放互斥锁 但是如果DoSomething的签名更改为 Task<int> DoSomeThingAsync(){/*...*/}; 做类似的事情吗?是否保证在输入时释放互斥锁?有没有更简单的方法?(我不能使用async关键字,所以请只考虑TPL)您不能以那种方式使用Monitor,因为Monitor是线程仿射的,在您的情况下,任务和延续可能在不同的线程上运行 要使用的适当同步机制是将信号量lim(不是线程仿射)设置为1: public Sem

在正常情况下,我们写

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

但是如果
DoSomething
的签名更改为

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

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

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

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

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

_semaphore.Wait();
return DoSomethingAsync().ContinueWith(t =>
{
    _semaphore.Release();
    return t.Result;
});
只要您不使用
taskcontinuation选项之一,例如
OnlyOnFaulted
onlyoncancelled
,任务完成后,将始终运行continuation,因此保证释放信号量

return Task.Factory.StartNew(() =>
{
    Monitor.Enter(mutex);
    return DoSomethingAsync();
}).Unwrap().ContinueWith(t =>
{
    Monitor.Exit(mutex);
    return t;
}).Unwrap();
public SemaphoreSlim _semaphore = new SemaphoreSlim(1,1);

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