异步锁SemaphoreSlim

可以使用异步锁SemaphoreSlim使异步程序串行,在等待锁时,可以设置一个超时时间,一旦超时时,WaitAsync会返回一个bool量,通过这个bool量确认是否要运行相应的代码,如果超时,即返回false时,此时不能Release,只有true时,才需要Release异步锁。

private static readonly SemaphoreSlim _mutex = new SemaphoreSlim(1, 1);

public static async void WaitAync(int index)
{
    bool flag= await _mutex.WaitAsync(millisecondsTimeout);
    Console.WriteLine($"{index}, {flag}, Enter, {DateTime.Now:yyyy - MM - ddTHH:mm: ss.fff}");
    if (flag)
    {
        try
        {
            await Task.Delay(1000);
            count++;
            Console.WriteLine($"{index}, {count}");
        }
        catch (Exception)                {

            throw;
        }
        finally
        {
            Console.WriteLine($"{index}, Release, {DateTime.Now:yyyy - MM - ddTHH:mm: ss.fff}");
            _mutex.Release();
        }
    }
}

Semaphore 和 SemaphoreSlim

信号量和线程标识

  1. 两种信号量类型不会在对 WaitOne、Wait、Release 和 SemaphoreSlim.Release 方法的调用上强制线程标识。 例如,信号量的一种常见使用方案涉及制造者线程和使用者线程,其中一个线程始终增加信号量计数,另一个始终减少信号量计数。
  2. 程序员有责任确保线程不会过多次地地释放信号量。 例如,假定信号量的最大计数为 2 并且线程 A 和线程 B 都进入了该信号量。 如果线程 B 中的编程错误导致它两次成功调用了 Release。 信号灯计数已满,当线程 A 最终调用 Release 时,SemaphoreFullException 抛出。
  3. 信号灯有两种类型:本地信号灯和命名系统信号灯。 本地信号灯是应用程序的本地信号量,系统信号量在整个操作系统中可见,适合进程间同步。 这是SemaphoreSlim不使用内核信号量Windows类的轻型替代Semaphore方法。 与类 Semaphore 不同,该 SemaphoreSlim 类不支持命名的系统信号灯。 只能将其用作本地信号灯。 类 SemaphoreSlim 是建议在单个应用中同步的信号灯。