2013-05-25 3 views
2

Я пытаюсь контролировать доступ к буферу 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; 
     } 
    } 
} 
+0

«семафор никогда не уменьшает счетчик» Чтение счетчика внутри семафора не является хорошим способом, чтобы увидеть, если он работает. Попробуйте правильно объяснить свою проблему. – Euphoric

+0

Вместо использования поля '_data', я думаю, что лучший способ - использовать лямбда. Например. 'new Thread (() => Set (data))'. – svick

+0

Семафор ничего не защищает, он не нужен. –

ответ

2

Вы немедленно освободить семафор после запуска нити Set. В то время как она выполняется семафор может быть 1 или 0. Переместите код Realease в 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(); 
} 
Смежные вопросы