等待Task.Run(()=> semaphore.WaitOne())有什么问题吗?
标题说明了一切。 await Task.Run(() => semaphore.WaitOne());
有什么问题await Task.Run(() => semaphore.WaitOne());
? System.Threading.Semaphore
不是线程仿射的,所以我不认为会有问题。 我知道SemaphoreSlim
类是可用的,但我需要进行跨进程同步,而SemaphoreSlim
不会这样做。
或者我可以/应该创建自己的自定义类型的WaitHandle
吗?
如果你想在这里等待信号量时保持UI响应,那可能是有意义的,但有一个问题: “信号量没有所有者” 。 如果您在两个进程之间共享信号量,而另一个进程在不调用Semaphore.Release()
情况下崩溃, 则共享资源的所有权将丢失 。 剩下的过程可能无法再次获取它。
IMO, Mutex
语义在这里更合适,但是对于Mutex
你需要线程亲和力。 也许,您可以获取互斥锁,访问资源并在同一线程上释放它:
await Task.Factory.StartNew(() => { mutex.WaitOne(); try { // use the shared resource } finally { mutex.ReleaseMutex(); } }, TaskCreationOptions.LongRunnning);
如果这不可能(例如,因为您需要访问主UI线程上的共享资源),您可以使用专用线程作为互斥锁。 这可以通过自定义任务调度程序来完成,例如,使用numberOfThreads:1
Stephen Toub的StaTaskScheduler
(在这种情况下,辅助线程不必是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 for Windows Store应用程序 )或Windows Phone,那么Task.Factory.StartNew
w / TaskCreationOptions.LongRunning
仍然存在,你可以使用它代替new Thread()
与StaTaskScheduler
或者类似我的ThreadWithSerialSyncContext
只要你需要一个具有亲和力的后台线程。