【发布时间】:2014-10-12 12:06:21
【问题描述】:
我需要访问由两个进程共享的 Windows 8.1 应用程序中的资源:应用程序本身和后台任务,所以我需要一个名为 Semaphore,SemaphoreSlim 不适用于那里,因为我在之间进行异步工作获取和释放我不能使用Mutex。
我在 PCL 中创建了一个类,该类创建信号量并允许我以这种方式等待 WaitOne 方法:
public sealed class AsyncSemaphore:IDisposable
{
Semaphore _semaphore;
public AsyncSemaphore(int initialCount, int maximumCount, string name)
{
_semaphore = new Semaphore(initialCount, maximumCount, name);
}
public IAsyncOperation<bool> WaitOneAsync()
{
return AsyncInfo.Run<bool>(cancellationToken =>
Task.Run(()=>{
while (!_semaphore.WaitOne(100))
{
Logger.Log("Waiting...");
cancellationToken.ThrowIfCancellationRequested();
}
return true;
},cancellationToken));
}
public int Release()
{
return _semaphore.Release();
}
public void Dispose()
{
if (_semaphore != null)
{
_semaphore.Dispose();
_semaphore = null;
}
}
}
但是WaitOneAsync也可以这样写:
public IAsyncOperation<bool> WaitOneAsync()
{
return AsyncInfo.Run<bool>(async cancellationToken =>
{
while (!_semaphore.WaitOne(0))
{
Logger.Log("Waiting...");
await Task.Delay(100, cancellationToken);
}
return true;
});
}
然后我在我的代码中这样使用它:
_semaphore= new AsyncSemaphore(1,1,"uniquename");
//....
await _semaphore.WaitOneAsync();
try
{
//do more async work
}
finally
{
_semaphore.Release();
}
这是正确的吗?哪一个最好并且使用更少的资源?
【问题讨论】:
-
如果不是 SemaphoreSlim,_semaphore 是什么类型?
-
它是一个 System.Threading.Semaphore,所以我可以使用命名信号量。 SemaphoreSlim 不允许使用命名的,因此它不会在两个不同的进程之间锁定,我添加了一些代码来澄清......
-
不,这不正确。 WaitOne(100) 不像您的替代品那样具有 100 毫秒的最坏情况行为。
-
@Hans 很好的发现!当我写第二个选项时,我没有注意到这一点。谢谢。
-
@jmservera:在完整的桌面框架上,您可以使用
ThreadPool.RegisterWaitForSingleObject。但是,在 Win8 上,您确实需要阻止线程池线程或轮询。在这两个中,我会选择阻塞线程池线程。
标签: c# async-await semaphore c#-5.0 winrt-async