Description

Release() Release(int)

Release one or a specified number of Tasks.

Wait(CancellationToken)

Wait(int)

Wait(TimeSpan)

Wait(int, CancellationToken) Wait(TimeSpan, CancellationToken) CurrentCount

Calls to this method block until the event is set, the specified time period has passed, or the specified token is cancelled.

Return the number of Tasks that will be released or the number of times that Wait() can be called without blocking if there are no waiting Tasks.

Listing 4-18 demonstrates the use of this class. Ten worker Tasks are created and call the SemaphoreSlim.Wait() method. A supervisor Task periodically releases two threads by signaling the primitive by calling SemaphoreSlim.Release(2).

Listing 4-18. Using the SemaphoreSlim Class using System;

using System.Threading;

using System.Threading.Tasks;

namespace Listing_18 {

class Listing_18 {

static void Main(string[] args) {

// create the primtive

SemaphoreSlim semaphore = new SemaphoreSlim(2);

// create the cancellation token source CancellationTokenSource tokenSource = new CancellationTokenSource();

// create and start the task that will wait on the event for (int i = 0; i < 10; i++) { Task.Factory.StartNew(() => { while (true) {

semaphore.Wait(tokenSource.Token); // print out a message when we are released Console.WriteLine("Task {0} released", Task.CurrentId);

}, tokenSource.Token);

// create and start the signalling task Task signallingTask = Task.Factory.StartNew(() => { // loop while the task has not been cancelled while (!tokenSource.Token.IsCancellationRequested) { // go to sleep for a random period tokenSource.Token.WaitHandle.WaitOne(500); // signal the semaphore semaphore.Release(2); Console.WriteLine("Semaphore released");

// if we reach this point, we know the task has been cancelled tokenSource.Token.ThrowIfCancellationRequested(); }, tokenSource.Token);

// ask the user to press return before we cancel // the token and bring the tasks to an end Console.WriteLine("Press enter to cancel tasks"); Console.ReadLine();

// cancel the token source and wait for the tasks tokenSource.Cancel();

// wait for input before exiting Console.WriteLine("Press enter to finish"); Console.ReadLine();

There are no guarantees about which of the waiting Tasks will be released when the Release() method is called. If you compile and run the listing, you will see something similar to the following output, which illustrates that the order in which Tasks call the Wait() method has no relationship to the order in which they are released:

Semaphore released Task 4 released Task 3 released Semaphore released Task 6 released Task 9 released Semaphore released Task l0 released Task 7 released Semaphore released Task 2 released Task 4 released

If there are no Tasks waiting when you call Release() ,the event remains set until the Wait() method has been called. If you specified a number to release by providing an integer argument, the event remains set until the Wait() method has been called the number of times you specified.

0 0

Post a comment