等待Task.Run(()=> semaphore.WaitOne())有什么问题吗?
标题说明了一切。 await Task.Run(() => semaphore.WaitOne());
有什么问题await Task.Run(() => semaphore.WaitOne());
? System.Threading.Semaphore
不是线程仿射的,所以我不认为会有问题。 我知道SemaphoreSlim
类可用,但我需要做跨进程同步,而SemaphoreSlim
不会那样做。
或者可以/我应该创建自己的自定义类型的WaitHandle
吗?
如果你想在这里等待信号量的时候保持UI的响应,这可能是有道理的,但有一个问题:“信号量没有所有者”。 如果您在两个进程之间共享信号量,并且另一个进程崩溃而不调用Semaphore.Release()
, 则共享资源的所有权将会丢失 。 剩下的过程可能无法再次获取它。
国际海事组织, Mutex
语义在这里会更合适,但使用Mutex
你需要线程亲和力。 也许,你可以获得互斥体,访问资源并在相同的线程上释放它:
await Task.Factory.StartNew(() =>
{
mutex.WaitOne();
try
{
// use the shared resource
}
finally
{
mutex.ReleaseMutex();
}
}, TaskCreationOptions.LongRunnning);
如果这是不可能的(例如,因为您需要访问主UI线程上的共享资源),则可以使用专用线程来处理互斥锁。 这可以通过一个自定义的任务调度程序完成,例如Stephen Toub的带有numberOfThreads:1
的StaTaskScheduler
numberOfThreads:1
(在这种情况下,帮助程序线程不必做STA):
using (var scheduler = new StaTaskScheduler(numberOfThreads: 1))
{
await Task.Factory.StartNew(
() => mutex.WaitOne(),
CancellationToken.None,
TaskCreationOptions.None,
scheduler);
try
{
// use the shared resource on the UI thread
}
finally
{
Task.Factory.StartNew(
() => mutex.ReleaseMutex(),
CancellationToken.None,
TaskCreationOptions.None,
scheduler).Wait();
}
}
更新 ,如果你担心WinRT(即.NET的Windows应用商店应用)或Windows Phone,那么Task.Factory.StartNew
w / TaskCreationOptions.LongRunning
仍然存在,你可以使用它而不是new Thread()
与StaTaskScheduler
或者当你需要一个具有亲和力的后台线程时,像我的ThreadWithSerialSyncContext
。
上一篇: Is there anything wrong with await Task.Run(() => semaphore.WaitOne())?
下一篇: How to get numbers of online users using .NET Identity 2.0 in MVC 5