多线程同步和UI线程同步.能做到吗

本文关键字:同步 线程 UI 多线程 | 更新日期: 2023-09-27 17:54:53

我正在制作一个库,该库允许访问系统范围的共享资源,并希望对其使用类似互斥锁的锁。我过去曾使用Mutex类来同步不同线程或进程中的操作。

在UI应用程序中,可能会出现问题。我正在制作的库用于多个产品,其中一些是位于同一主机UI应用程序中的插件。因此,UI线程对于库的每个实例都是相同的,因此即使资源已经被访问,mutex.WaitOne()也将返回true。

"资源"是用户的注意力。我不希望打开多个特定的子窗口,无论哪个主机进程想打开它。此外,它可能是一个不同的线程,知道何时可以释放互斥对象(子窗口关闭(。

有没有一个类或模式可以让我轻松地解决这个问题?

概括一下我的意图,这可能是理想的虚构类:

var specialMutex = new SpecialMutex("UserToastNotification");
specialMutex.WaitOne(0); // Returns true only once, even on the same thread,
                         // and is respected across different processes.
specialMutex.Release();  // Can be called from threads other than the one
                         // that called WaitOne();

是的,Release看起来很危险,但它只是由资源调用的。

多线程同步和UI线程同步.能做到吗

我想您想要一个初始值为1的信号量。在Semaphore上对WaitOne()的任何调用都会尝试递减计数,而与线程无关。对Release的任何调用,无论调用它的线程是什么,都会导致计数递增。

因此,如果一个线程用值1初始化信号量,然后调用WaitOne,则计数将变为0。如果同一线程在同一信号量上再次调用WaitOne,则该线程将锁定等待释放。

其他一些线程可以调用Release来增加计数。

因此,尽管SemaphoreMutex并不完全相似,但它可能足够相似,可以让您的程序正常工作。

您可以使用比较/交换操作来完成此操作。类似这样的东西:

class Lock {
  int locked = 0;
  bool Enter() { return Interlocked.CompareExchange(ref locked, 1, 0) == 0; }
  void Leave() { Interlocked.CompareExchange(ref locked, 0, 1); }
}

在这里,Enter只会返回true一次,无论它是从哪个线程调用的,直到您调用leave。