Ear*_*ine 4 .net c# synchronization task-parallel-library
在正常的C#中我们写
int DoSomething(){/*...*/)};
lock(mutex)
{
return DoSomething();
}
Run Code Online (Sandbox Code Playgroud)
确保在所有情况下都mutex被释放.
但如果签名DoSomething改为
Task<int> DoSomeThingAsync(){/*...*/};
Run Code Online (Sandbox Code Playgroud)
是否有以下代码
return Task.Factory.StartNew(() =>
{
Monitor.Enter(mutex);
return DoSomethingAsync();
}).Unwrap().ContinueWith(t =>
{
Monitor.Exit(mutex);
return t;
}).Unwrap();
Run Code Online (Sandbox Code Playgroud)
做类似的事情?是否保证mutex在输入时释放?有没有更简单的方法呢?(我无法使用async关键字,所以请继续考虑TPL)
你不能Monitor以这种方式使用,因为它Monitor是线程仿射的,在你的情况下,任务和延续可能在不同的线程上运行.
要使用的适当同步机制是SemaphoreSlim(不是线程仿射)设置为1:
public SemaphoreSlim _semaphore = new SemaphoreSlim(1,1);
_semaphore.Wait();
return DoSomethingAsync().ContinueWith(t =>
{
_semaphore.Release();
return t.Result;
});
Run Code Online (Sandbox Code Playgroud)
只要你不使用的一个TaskContinuationOptions如OnlyOnFaulted或OnlyOnCanceled任务已经完成,因此该信号可以保证被释放后的延续将始终运行.