Luke101
Luke101

Reputation: 65238

How to implement a global semaphore class

I am trying to control access to the windows clipboard by using a semaphore. I need this semaphore to be global throughout the application because several thread access the semaphore to save data to the windows clipboard. The problem I am facing is the semaphore never decrements the counter. It is always 1 no matter how many threads access the semaphore.

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

Here is how I use the above code:

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;
        }
    } 
}

Upvotes: 3

Views: 2452

Answers (1)

I4V
I4V

Reputation: 35353

You immediately release the semaphore after starting the thread Set. While it is executed semaphore may be 1 or 0. Move the realease code to 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(); 
}

Upvotes: 2

Related Questions