这有什么错伺机Task.Run(()=> semaphore.WaitOne())? [英] Is there anything wrong with await Task.Run(() => semaphore.WaitOne())?
问题描述
标题说明了一切。这有什么错等待Task.Run(()=> semaphore.WaitOne());
? System.Threading.Semaphore
不是线程仿射,所以我不认为会有问题。我知道, SemaphoreSlim
类是可用的,但我需要做跨进程同步的,而 SemaphoreSlim
不做到这一点。
Title says it all. Is there anything wrong with await Task.Run(() => semaphore.WaitOne());
? System.Threading.Semaphore
isn't thread-affine, so I wouldn't think there would be a problem. I know that the SemaphoreSlim
class is available, but I need to do cross-process synchronization, and SemaphoreSlim
doesn't do that.
或CAN /我应该创建的WaitHandle
?
Or can/should I create my own custom type of WaitHandle
?
推荐答案
如果你想保持UI响应,同时等待信号量在这里,它可能是有意义的,但有一个问题:的信号灯没有所有者 的。如果你没有调用共享两个过程,另一个进程崩溃的信号量 Semaphore.Release()
,的所有权的共享资源将会丢失。剩余的过程可能不能够再次获得它
If you're trying to keep the UI responsive while waiting for the semaphore here, it might make sense, but there's a catch: "Semaphores don't have owners". If you share the semaphore between two processes, and the other process crashes without calling Semaphore.Release()
, the ownership over the shared resource will be lost. The remaining process may not be able to acquire it again.
海事组织, 互斥
语义会比较适合这里,但互斥
你需要线程关联。或许,你可以获取互斥锁,访问资源,并在同一个线程释放它:
IMO, the Mutex
semantic would be more appropriate here, but with Mutex
you'd need thread affinity. Perhaps, you can acquire the mutex, access the resource and release it on the same thread:
await Task.Factory.StartNew(() =>
{
mutex.WaitOne();
try
{
// use the shared resource
}
finally
{
mutex.ReleaseMutex();
}
}, TaskCreationOptions.LongRunnning);
如果这是不可能的(例如,因为你需要访问共享资源的主UI线程),你可以使用一个专用线程互斥体。这可以通过自定义任务计划程序,如进行斯蒂芬Toub的 StaTaskScheduler
与 numberOfThreads:1
(助手线程没有在这种情况下必须作出STA):
If that's not possible (e.g., because you need to access the shared resource on the main UI thread), you could use a dedicated thread for the mutex. This can be done with a custom task scheduler, e.g. Stephen Toub's StaTaskScheduler
with numberOfThreads:1
(the helper thread doesn't have to be made STA in this case):
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手机,那么 Task.Factory.StartNew
W / TaskCreationOptions.LongRunning
仍然存在,您可以使用新的Thread()
与 StaTaskScheduler
或类似的东西,而不是我 ThreadWithSerialSyncContext
当你需要与亲和力的后台线程。
Updated, if you're concerned about WinRT (i.e., .NET for Windows Store Apps) or Windows Phone, then Task.Factory.StartNew
w/ TaskCreationOptions.LongRunning
is still there, you can use it instead of new Thread()
with StaTaskScheduler
or something like my ThreadWithSerialSyncContext
whenever you need a background thread with affinity.
这篇关于这有什么错伺机Task.Run(()=> semaphore.WaitOne())?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!