Я использую Mutex.TryOpenExisting(). Я хотел знать, является ли потокобезопасным?
public class MutexNamedSystemDemo
{
private const string _mutexName = @"Global\{C7F2DE44-8927-4B01-B8E1-D8F158A483A8}";
private static Mutex _mutex;
private static bool _intiallyOwned = false;
private static int _count = 0;
/*public MutexNamedSystemDemo()
{
_mutex = new Mutex(_intiallyOwned, _mutexName);
}*/
public void Main()
{
if (Mutex.TryOpenExisting(_mutexName, out _mutex) == false)
_mutex = new Mutex(_intiallyOwned, _mutexName);
}
}
Иногда при выполнении возникает ошибка _mutex — это null. Если это потокобезопасно, почему это происходит?
@EtiennedeMartel, я думаю, что реальный вопрос: «Является ли TryOpen + new Mutex() потокобезопасным в целом?». И ответ будет «нет». И правильная реализация такого случая показана в ответе.





Похоже, вы хотите проверить, существует ли мьютекс с заданным именем, а затем, если он его использует, в противном случае создайте его.
Если это так, то вообще не нужно звонить Mutex.TryOpenExisting.
Вам просто нужно:
_mutex = new Mutex(_intiallyOwned, _mutexName);
Это связано с тем, что в документации конструктора Mutex(Boolean, String) указано, что:
Если указано имя и объект синхронизации запрошенного типа уже существует в пространстве имен, используется существующий объект синхронизации.
Т.е. он гарантирует нужное вам поведение.
Отвечая на ваш вопрос относительно потокобезопасности: да, Mutex.TryOpenExisting сам по себе потокобезопасен.
Из документации класса Mutex:
Этот тип является потокобезопасным.
Это не означает, что вызов Mutex.TryOpenExisting и последующий вызов конструктора в целом является атомарным, но, как я объяснил выше, в этом нет необходимости.
И последнее замечание: все это не объясняет ваш null. Поскольку вы не упомянули об исключении, вызванном конструктором, я считаю, что это результат других частей вашего кода, которые не показаны выше.
В разделе «потокобезопасность» в конце документации
Mutexнаписано «этот тип потокобезопасен». Так что да, это так.