这有什么错伺机Task.Run(()=> semaphore.WaitOne())? [英] Is there anything wrong with await Task.Run(() => semaphore.WaitOne())?

查看:218
本文介绍了这有什么错伺机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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆