等待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只要你需要一个具有亲和力的后台线程。