问题描述
在普通的C#我们写
int DoSomething(){/*...*/)};
lock(mutex)
{
return DoSomething();
}
要确保在互斥
发布的所有情况。
to ensure in all cases the mutex
is released.
但是,如果的DoSomething
的签名更改为
But if the signature of DoSomething
changed to
Task<int> DoSomeThingAsync(){/*...*/};
执行以下操作code
Does the following code
return Task.Factory.StartNew(() =>
{
Monitor.Enter(mutex);
return DoSomethingAsync();
}).Unwrap().ContinueWith(t =>
{
Monitor.Exit(mutex);
return t;
}).Unwrap();
做类似的事情?它是保证释放互斥
每当有人进来?有没有更简单的方法,这样做? (我不能够使用异步
关键字,所以保持TPL想着只)
do similar things? Is it guaranteed to release the mutex
whenever it was entered? Are there any simpler way to do so? (I am not able to use the async
keyword so keep thinking in TPL only)
推荐答案
您无法使用显示器
以这种方式,因为显示器
是线程仿射和你的案件的任务,并继续可以运行在不同的线程。
You can't use Monitor
in that way because Monitor
is thread-affine and in your case the task and continuation may run on different threads.
要使用适当的同步机制是 SemaphoreSlim
(这是不是线程仿射)设置为1:
The appropriate synchronization mechanism to use is a SemaphoreSlim
(which isn't thread-affine) set to 1:
public SemaphoreSlim _semaphore = new SemaphoreSlim(1,1);
_semaphore.Wait();
return DoSomethingAsync().ContinueWith(t =>
{
_semaphore.Release();
return t.Result;
});
只要你不使用的一个 TaskContinuationOptions
等 OnlyOnFaulted
或 OnlyOnCanceled
的延续将永远任务后运行已完成并因此该信号是保证被释放。
As long as you don't use one of the TaskContinuationOptions
such as OnlyOnFaulted
or OnlyOnCanceled
the continuation would always run after the task has completed and so the semaphore is guaranteed to be released.
这篇关于迁移锁TPL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!