且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

关于SemaphoreSlim与异步/等待使用

更新时间:2023-01-07 14:18:04


  

为什么10传递到SemaphoreSlim构造。


块引用>

他们使用 SemaphoreSlim 来限制到一次10个任务。信号灯是采取每一个任务开始前,每个任务释放它,当它完成。欲了解更多关于信号灯,请参见 MSDN


  

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


块引用>

Task.Delay 创建指定的时间间隔后完成并返回它的任务。大多数工作 -returning方法,如, Task.Delay 立即返回;它返回工作具有延迟。因此,如果code没有等待它,就不会有延迟。


  

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


块引用>

基于任务的异步模式工作对象返回热。这意味着他们已经通过他们回来的时候运行。在伺机Task.WhenAll 在最后等待他们全部完成。

I am not an advanced developer. I just try to get a hold on the task library and just googling. I never used the class SemaphoreSlim so I would like to know what it does. Here I present a code where SemaphoreSlim is used with async & await but which I do not understand. So I am pasting the code here. Please, could some one help me to understand the code below.

1st set of code

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();
}

Firstly, the WorkerMainAsync will be called and there a SemaphoreSlim is used. Why is 10 passed to the constructor of SemaphoreSlim.

When does the control come out of the while loop again?

What does ss.WaitAsync(); do?

The DoPollingThenWorkAsync() function is expecting a SemaphoreSlim but is not passed anything when it is called.......is this typo?

Why is await Task.Delay(3000); used?

They could simply use Task.Delay(3000) but why do they use await here instead.

2nd set of code for same purpose

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
  }
}

Here is a task & ss.Release added to a list....I really do not understand that after adding tasks to a list how they can run?

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

I am looking forward for a good explanation & help to understand the two sets of code. Thanks

why 10 is passing to SemaphoreSlim constructor.

They are using SemaphoreSlim to limit to 10 tasks at a time. The semaphore is "taken" before each task is started, and each task "releases" it when it finishes. For more about semaphores, see MSDN.

they can use simply Task.Delay(3000) but why they use await here.

Task.Delay creates a task that completes after the specified time interval and returns it. Like most Task-returning methods, Task.Delay returns immediately; it is the returned Task that has the delay. So if the code did not await it, there would be no delay.

just really do not understand after adding task to list how they can run?

In the Task-based Asynchronous Pattern, Task objects are returned "hot". This means they're already running by the time they're returned. The await Task.WhenAll at the end is waiting for them all to complete.