关于使用Async/Await的SemaphoreSlim的用法

Tho*_*mas 5 c# asynchronous semaphore async-await

我不是高级开发人员.我只是试图抓住任务库,只是谷歌搜索.我从来没有上过课,SemaphoreSlim所以我想知道它是做什么的.在这里,我提供了一个代码,其中SemaphoreSlim使用async但我不明白.所以我在这里粘贴代码.请帮助我理解下面的代码.

第一组代码

await WorkerMainAsync();

async Task WorkerMainAsync()
{
    SemaphoreSlim ss = new SemaphoreSlim(10);
    while (true)
    {
        await ss.WaitAsync();
        // you should probably store this task somewhere and then await it
        var task = DoPollingThenWorkAsync();
    }
}

async Task DoPollingThenWorkAsync(SemaphoreSlim semaphore)
{
    var msg = Poll();
    if (msg != null)
    {
        await Task.Delay(3000); // process the I/O-bound job
    }

    // this assumes you don't have to worry about exceptions
    // otherwise consider try-finally
    semaphore.Release();
}
Run Code Online (Sandbox Code Playgroud)

首先,await将调用它并WorkerMainAsync使用a.为什么10传递给的构造函数SemaphoreSlim.

控制什么时候再次出现在while循环中?

怎么10办?

SemaphoreSlim函数期待a while但是在被调用时没有传递任何东西.......这是错字吗?

为什么ss.WaitAsync();用?

他们可以简单地使用,DoPollingThenWorkAsync()但为什么他们SemaphoreSlim在这里使用.

用于相同目的的第二组代码

async Task WorkerMainAsync()
{
    SemaphoreSlim ss = new SemaphoreSlim(10);
    List<Task> trackedTasks = new List<Task>();
    while (DoMore())
    {
        await ss.WaitAsync();
        trackedTasks.Add(Task.Run(() => 
        {
            DoPollingThenWorkAsync();
            ss.Release();
        }));
    }
    await Task.WhenAll(trackedTasks);
}

void DoPollingThenWorkAsync()
{
    var msg = Poll();
    if (msg != null)
    {
        Thread.Sleep(2000); // process the long running CPU-bound job
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个任务并await Task.Delay(3000);添加到列表....我真的不明白,在列表中添加任务后如何运行?

trackedTasks.Add(Task.Run(async () => 
{
    await DoPollingThenWorkAsync();
    ss.Release();
}));
Run Code Online (Sandbox Code Playgroud)

我期待着一个很好的解释和帮助理解这两组代码.谢谢

Ste*_*ary 13

为什么10传递给SemaphoreSlim构造函数.

他们一次只能使用SemaphoreSlim10个任务.信号量在每个任务启动之前被"采用",每个任务在完成时"释放"它.有关信号量的更多信息,请参阅MSDN.

他们可以使用简单的Task.Delay(3000),但为什么他们在这里使用等待.

Task.Delay创建在指定时间间隔后完成并返回的任务.像大多数Task退回方法一样,Task.Delay立即返回; 它是Task有延迟的返回.因此,如果代码没有await,那就没有延迟.

只是真的不明白添加任务后列出它们如何运行?

基于任务的异步模式中,Task对象返回"热".这意味着他们在返回时已经在运行.将await Task.WhenAll在最后等待他们全部完成.

  • 顾名思义,`Task.Delay`返回表示延迟的任务."Semaphore"和"SemaphoreSlim"之间的区别在[相同的MSDN链接]中有所介绍(http://msdn.microsoft.com/en-us/library/z6zx288a%28v=vs.110%29.aspx).第一个代码示例有拼写错误; 它应该将`SemaphoreSlim`实例传递给worker方法. (2认同)
  • @participant:我觉得这很好.答案回答了问题,评论回答了评论中提出的其他问题. (2认同)