2015-01-19 3 views
5

Meine Anwendung verwendet .NET 4. Ich bin mit await async nuget packageMit erwarten SemaphoreSlim.WaitAsync in .NET 4

In meiner Anwendung ich eine await auf sempahore WaitAsync Aufruf tun wollen wie folgt.

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

Allerdings bekomme ich folgenden Kompilierungsfehler.

‚System.Threading.SemaphoreSlim‘ enthält keine Definition für ‚WaitAsync‘ enthalten und keine Erweiterungsmethode ‚WaitAsync‘ ein erstes Argument vom Typ ‚System.Threading.SemaphoreSlim‘ akzeptieren konnte gefunden werden (sind Sie fehlt eine using-Direktive oder ein Assemblyverweis?)

Könnte es 4.0 sowieso von uisng WaitAsync in .NET sein?

Antwort

5

Sie können SemaphoreSlim.WaitAsync in .Net 4.0 nicht verwenden, da diese Methode zu SemaphoreSlim in .Net 4.5 hinzugefügt wurde.

Sie können jedoch implementieren Ihre eigenen AsyncSemaphore folgenden Stephen Toub dem Beispiel in Building Async Coordination Primitives, 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); 
    } 
} 
1

Nein, Sie müssen auf .NET 4.5 aktualisieren (oder schreiben Sie eine WaitAsync Erweiterung (oder inhärent asynchronen Semaphor) selbst).

Die asynchronen Erweiterungen für .NET 4.0 ermöglichen die Unterstützung des eigentlichen Schlüsselworts await. Ein Großteil der Arbeit von .NET 4.5 besteht darin, asynchrone Operationen zu verschiedenen BCL-Typen hinzuzufügen, die erwartet werden können. Wenn Sie diese Vorgänge benötigen, müssen Sie die Version des von Ihnen verwendeten Frameworks aktualisieren.

1

WaitAsync wird mit .Net 4.5 eingeführt. Sie müssen sich entweder selbst als Erweiterung implementieren, indem Sie in source schauen (nicht sicher, ob das möglich ist), oder Sie können StephenToub's AsyncSemaphore verwenden.

1

Als WaitAsync nicht avaliable in .NET 4.0 können Sie den Code aus Stephan Toub's series of async synchronization primitives verwenden:

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