【问题标题】:How to implement a global semaphore class如何实现一个全局信号量类
【发布时间】:2013-05-25 15:11:51
【问题描述】:

我正在尝试通过使用信号量来控制对 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;
        }
    } 
}

【问题讨论】:

  • "信号量从不递减计数器" 读取信号量内部的计数器并不是查看它是否工作的好方法。请尝试正确解释您的问题。
  • 而不是使用_data 字段,我认为更好的方法是使用lambda。例如。 new Thread(() => Set(data)).
  • 信号量不保护任何东西,没有必要。

标签: c# semaphore


【解决方案1】:

在启动线程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(); 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2011-08-25
    • 2021-11-13
    • 2023-04-07
    相关资源
    最近更新 更多