如何实现一个全局信号量类

3

我正在尝试使用信号量控制对Windows剪贴板的访问。 我需要该信号量在整个应用程序中全局可用,因为多个线程需要访问该信号量以将数据保存到Windows剪贴板中。 我面临的问题是,信号量永远不会递减计数器。 无论有多少个线程访问该信号量,它始终为1。

namespace Global.GlobalLocks
{
    static public class Clipboard
    {
        static public readonly SemaphoreSlim ClipboardSemaphore = new SemaphoreSlim(1);
    }
}

以下是我使用上述代码的方法:
namespace Automator.Global
{
    static public class ClipBoard
    {
        static private string _data = string.Empty;

        static public void SetData(string data)
        {
            GlobalLocks.Clipboard.ClipboardSemaphore.Wait();
            _data = data;
            Thread t = new Thread(Set);
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            GlobalLocks.Clipboard.ClipboardSemaphore.Release(); 
        }

        static private void Set()
        {
            Clipboard.Clear();
            Clipboard.SetDataObject(_data, true);
        }

        static public string GetData()
        {
            return _data;
        }
    } 
}

"信号量永远不会减少计数器"。在信号量内部读取计数器并不是检查其工作方式的好方法。请尝试清楚地解释您的问题。 - Euphoric
不要使用_data字段,我认为更好的方法是使用lambda表达式。例如:new Thread(() => Set(data)) - svick
信号量不保护任何东西,它是不必要的。 - Hans Passant
1个回答

2

在启动线程Set后,立即释放信号量。当它执行时,信号量可能为1或0。将释放代码移动到Set中。

static public void SetData(string data)
{
    GlobalLocks.Clipboard.ClipboardSemaphore.Wait();
    _data = data;
    Thread t = new Thread(Set);
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
}

static private void Set()
{
     Clipboard.Clear();
     Clipboard.SetDataObject(_data, true);
     GlobalLocks.Clipboard.ClipboardSemaphore.Release(); 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接