Semaphoreslim应该在控制器中而不是在链中走下坡路吗?

时间:2018-11-24 07:17:29

标签: c# semaphore asp.net-core-webapi

在生产环境中,我们有类似僵局的行为,我想知道我们是否正确使用了信号量。

在我们的restapi中,代码如下所示:

public async Task<IActionResult> CreateAsync([FromBody] SomeModel someModel)
{
    var result = await _someClass.CreateArende(someModel);

    return result;
}

public async Task<IActionResult> RegisterAsync([FromBody] SomeModel someModel)
{
    var result = await _someClass.RegisterArende(someModel);

    return result;
}

我们的API控制器级别没有semphoreslim,但在someClass中看起来像这样:

public class SomeClass {

    protected static SemaphoreSlim _semphoreSlimCreateArende = new SemaphoreSlim(1, 1);

    public async virtual Task<SomeResponseDto> CreateArende(SomeModel someModel)
    {
        try
        {
            await _semphoreSlimCreateArende.WaitAsync();

        }
        finally
        {
            try
            {
                _semphoreSlimCreateArende.Release();
            }
            catch (Exception)
            {
            }
        }

        return new SomeResponseDto()
        {
            ...
        };
    }

    public async virtual Task<SomeResponseDto> RegisterArende(SomeModel someModel)
    {
        try
        {
            await _semphoreSlimCreateArende.WaitAsync();

        }
        finally
        {
            try
            {
                _semphoreSlimCreateArende.Release();
            }
            catch (Exception)
            {
            }
        }

        return new SomeResponseDto()
        {
            ...
        };
    }

}

信号量应该在控制器级别吗?还是应该将控制器的动作更改为不异步?

1 个答案:

答案 0 :(得分:1)

这个问题有点脱节,但是让我们尝试一下吧

首先让模式正确

try
{
    await _semphoreSlimCreateArende.WaitAsync();

    // do your sync work here

}
finally
{
    // if this throws you are certainly doing something wrong
    _semphoreSlimCreateArende.Release(); 
}

其次,为此,您应该从键盘上取下键盘

catch (Exception)
{
}

永远不要盲目地吃异常,如果您将它们放在_semphoreSlimCreateArende.Release上,那么您已经遇到了严重的问题,您必须找出原因

  

信号量应改为控制器级别吗?

在最有意义的级别使用它们,我的意思是,如果您需要在此处同步一段代码,而不是在13个级别上进行同步。

  

还是应该将控制器操作更改为不异步?

如果您有asnyc的工作,请使控制器async并使其沿堆栈向下传播到您的async代码

  

在生产环境中,我们的行为像僵局一样,   想知道我们是否正确使用了信号量。

哇,我们是在谈论数据库死锁,还是上下文死锁。不管怎样,这听起来有点可疑

仅供参考

在基于Web的服务中使用SemaphoreSlim是一种讨厌的方法。 SemaphoreSlim适用于自旋锁,不应在任何时间段内被阻塞使用。自旋锁咀嚼处理器,等待释放锁。理想的情况是,在锁被咬得很少的情况下,并且在不会进一步阻塞的情况下使用它们。

如果您正在使代码死锁,那么您需要找出导致死锁的确切原因,如果死锁是基于任务的死锁,那么SemaphoreSlim不是正确的工具,如果它是非阻塞的种族条件,那么也许可以接受。如果它是数据库死锁,那么您会有更大的问题。