Usage are waiting for SemaphoreSlim.WaitAsync in .NET 4

My application uses .NET 4. I am using await async using the nuget package

In my application, I want to make the wait when calling sempahore WaitAsync as follows.

SemaphoreSlim semphore = new SemaphoreSlim(100); await semphore.WaitAsync(); 

However, I get the following compilation error.

'System.Threading.SemaphoreSlim' does not contain a definition for WaitAsync, and the WaitAsync extension method cannot be found that takes the first argument of the type "System.Threading.SemaphoreSlim" (do you miss the using directive or the assembly reference?)

Could uisng WaitAsync be anyway in .NET 4.0?

+5
source share
7 answers

You cannot use SemaphoreSlim.WaitAsync in .Net 4.0, since this method was added to SemaphoreSlim in .Net 4.5.

However, you can use your own AsyncSemaphore following Stephen AsyncSemaphore example, Building Primitives for Asynchronous Coordination, Part 5: AsyncSemaphore :

 public class AsyncSemaphore { private readonly static Task s_completed = Task.FromResult(true); private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>(); private int m_currentCount; public AsyncSemaphore(int initialCount) { if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount"); m_currentCount = initialCount; } public Task WaitAsync() { lock (m_waiters) { if (m_currentCount > 0) { --m_currentCount; return s_completed; } else { var waiter = new TaskCompletionSource<bool>(); m_waiters.Enqueue(waiter); return waiter.Task; } } } public void Release() { TaskCompletionSource<bool> toRelease = null; lock (m_waiters) { if (m_waiters.Count > 0) toRelease = m_waiters.Dequeue(); else ++m_currentCount; } if (toRelease != null) toRelease.SetResult(true); } } 
+5
source

As already mentioned, .NET 4.5 introduced SemaphoreSlim.WaitAsync .

For .NET 4.0, you can write your own asynchronous lock, or use one of my Nito.AsyncEx NuGet packages .

+3
source

WaitAsync is introduced with .Net 4.5. You need to either implement yourself as an extension method by looking at source (not sure if this is possible), or you can use StephenToub AsyncSemaphore .

+2
source

No, you will need to upgrade to .NET 4.5 (or write the WaitAsync extension (or essentially an asynchronous semaphore)).

Asynchronous extensions for .NET 4.0 support the actual await keyword. Most of the work of .NET 4.5 adds asynchronous operations to the various types of BCL that you can expect. If you need these operations, you need to update the version of the structure used.

+1
source

Since WaitAsync not available in .NET 4.0, you can use code from the Stephan Toub series of asynchronous synchronizations :

 public class AsyncSemaphore { private readonly static Task s_completed = Task.FromResult(true); private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>(); private int m_currentCount; public AsyncSemaphore(int initialCount) { if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount"); } m_currentCount = initialCount; } public Task WaitAsync() { lock (m_waiters) { if (m_currentCount > 0) { --m_currentCount; return s_completed; } else { var waiter = new TaskCompletionSource<bool>(); m_waiters.Enqueue(waiter); return waiter.Task; } } } public void Release() { TaskCompletionSource<bool> toRelease = null; lock (m_waiters) { if (m_waiters.Count > 0) toRelease = m_waiters.Dequeue(); else ++m_currentCount; } if (toRelease != null) toRelease.SetResult(true); } } 
+1
source

The AysncSemaphore class published in the other two answers does not compile with Framework 4.0, because Task.FromResult is not defined.

This is my alternate version:

 public class AsyncSemaphore { private readonly static Task s_completed ; private readonly Queue<TaskCompletionSource<bool>> m_waiters = new Queue<TaskCompletionSource<bool>>(); private int m_currentCount; static AsyncSemaphore() { var tcs = new TaskCompletionSource<bool>(); tcs.SetResult(true); s_completed = tcs.Task ; } public AsyncSemaphore(int initialCount) { if (initialCount < 0) throw new ArgumentOutOfRangeException("initialCount"); m_currentCount = initialCount; } public Task WaitAsync() { lock (m_waiters) { if (m_currentCount > 0) { --m_currentCount; return s_completed; } else { var waiter = new TaskCompletionSource<bool>(); m_waiters.Enqueue(waiter); return waiter.Task; } } } public void Release() { TaskCompletionSource<bool> toRelease = null; lock (m_waiters) { if (m_waiters.Count > 0) toRelease = m_waiters.Dequeue(); else ++m_currentCount; } if (toRelease != null) toRelease.SetResult(true); } } 
0
source

In my application, I want to make the wait when calling Sempahore WaitAsync as follows.

SemaphoreSlim semphore = new SemaphoreSlim (100); await semphore.WaitAsync ();

However, I get the following compilation error.

"System.Threading.SemaphoreSlim" does not contain a definition for "WaitAsync" and no extension method "WaitAsync" was found that takes the first argument of the type "System.Threading.SemaphoreSlim" (is there no directive using or a reference to the assembly?)

Could there be anyway using WaitAsync in .NET 4.0?

0
source

Source: https://habr.com/ru/post/1211424/


All Articles