我的应用程序使用的是.NET 4.我正在使用nuget package
等待异步在我的应用程序中,我想对sempahore WaitAsync调用进行等待,如下所示。
SemaphoreSlim semphore = new SemaphoreSlim(100);
await semphore.WaitAsync();
但是我遇到了编译错误。
'System.Threading.SemaphoreSlim'不包含'WaitAsync'的定义,并且没有可以找到接受类型为'System.Threading.SemaphoreSlim'的第一个参数的扩展方法'WaitAsync'(你是否缺少using指令或汇编参考?)
在.NET 4.0中,无论如何都可以使用uisng WaitAsync吗?
答案 0 :(得分:5)
您无法在.Net 4.0中使用SemaphoreSlim.WaitAsync
,因为此方法已添加到.Net 4.5中的SemaphoreSlim
。
然后,您可以在Building Async Coordination Primitives, Part 5: AsyncSemaphore中跟随Stephen Toub的示例实现您自己的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 :(得分:3)
正如其他人所提到的,.NET 4.5引入了SemaphoreSlim.WaitAsync
。
对于.NET 4.0,您可以write your own async-compatible lock中的use one或Nito.AsyncEx NuGet package。
答案 2 :(得分:2)
WaitAsync
。您需要通过查看source(不确定是否可能)来实现自己作为扩展方法,或者您可以使用StephenToub的AsyncSemaphore。
答案 3 :(得分:1)
不,你需要升级到.NET 4.5(或者自己写一个WaitAsync
扩展名(或固有的异步信号量))。
.NET 4.0的异步扩展允许支持实际的await
关键字。 .NET 4.5的大部分工作是向可以等待的各种BCL类型添加异步操作。如果您需要这些操作,则需要升级您使用的框架版本。
答案 4 :(得分:1)
作为{{1&#39;在.NET 4.0中可用,您可以使用Stephan Toub's series of async synchronization primitives中的代码:
WaitAsync
答案 5 :(得分:0)
在另外两个答案中发布的类AysncSemaphore不能与Framework 4.0一起编译,因为未定义Task.FromResult。
这是我的替代版本:
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);
}
}