2016-12-03 5 views
0

Я не хочу блокировать некоторый код между процессами, это в основном для моего приложения UWP, но поскольку это кросс-платформенный проект, этот фрагмент кода также выполняется в приложении для Android:Xamarin Android: Semaphore.TryOpenExisting не работает

if (!Semaphore.TryOpenExisting("some_name", out _semaphore)) 
    _semaphore = new Semaphore(1, 1, "some_name"); 

Где _semaphore является:

private readonly Semaphore _semaphore; 

Так что теперь, когда Semaphore.TryOpenExisting называется, я получаю следующее исключение: System.NotSupportedException: Specified method is not supported..

Но, глядя на Xamarin Docs, похоже, что выполняется Semaphore.TryOpenExisting, и я не вижу никакой информации, которая не поддерживается на некоторых платформах?

Что я делаю неправильно? Должен ли я расколоть класс Semaphore для кросс-платформенного? Как я могу достичь этого в кросс-платформенном сценарии?

+0

какой-либо причине вы не можете использовать что-то вроде SemaphoreSlim? Чего вам нужно сделать, чего с этим не может быть достигнуто? – Cheesebaron

+0

'СемафорСлим' - это локальный семафор для блокировки в приложении и не имеет функций для названных семафоров. Мне нужен межпроцесс под названием Семафор –

ответ

0

Итак, поскольку для Android мне не нужна синхронизация между процессами, предоставляемая классическим классом System.Threading.Semaphore, который выглядит как не поддерживаемый в Xamarin.Android, но я все еще хотел иметь функцию семафоров в процессе иметь согласованное поведение с моим приложением UWP, я написал следующий вспомогательный класс для запуска кода в «под названием» замок с помощью SemaphoreSlim класс:

class NamedSlimLocker 
{ 
    private static readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreSlimDict; 
    static NamedSlimLocker() 
    { 
     _semaphoreSlimDict = new ConcurrentDictionary<string, SemaphoreSlim>(); 
    } 

    private readonly string _name; 
    private readonly SemaphoreSlim _semaphore; 

    public NamedSlimLocker(string name) 
    { 
     this._name = name; 
     _semaphore = _semaphoreSlimDict.GetOrAdd(name, (n) => new SemaphoreSlim(1,1)); 
    } 

    public async Task RunLockedAsync(Func<Task> action) 
    { 
     try 
     { 
      await _semaphore.WaitAsync(); 
      await action(); 
     } 
     finally 
     { 
      _semaphore.Release(); 
     } 
    } 

    public async Task<T> RunLockedAsync<T>(Func<Task<T>> action) 
    { 
     try 
     { 
      await _semaphore.WaitAsync(); 
      return await action(); 
     } 
     finally 
     { 
      _semaphore.Release(); 
     } 
    } 
} 
Смежные вопросы