迁移锁TPL [英] Migrating lock to TPL

查看:182
本文介绍了迁移锁TPL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在普通的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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆