Это правильное использование мьютекса?

У меня есть ситуация, когда у меня может быть несколько экземпляров программы, запущенной сразу, и важно, чтобы одна только одна функция не выполнялась одновременно в нескольких экземплярах.

Правильно ли это использовать мьютексы, чтобы это не происходило?

lock (this.GetType()) {
    _log.Info("Doing Sync");
    DoSync();
    _log.Info("Sync Completed");
}

Ответ 1

Вы сказали несколько экземпляров одного приложения, поэтому мы говорим о двух запусках program.exe, правильно? Оператор блокировки не будет блокировать несколько программ, как раз внутри программы. Если вам нужен настоящий Mutex, посмотрите на объект System.Threading.Mutex.

Вот пример использования:

bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
    try
    {
        mtx.WaitOne();

        MessageBox.Show("Click OK to release the mutex.");
    }
    finally
    {
        mtx.ReleaseMutex();
    }
}

Созданная новая переменная сообщит вам, была ли она создана в первый раз. Тем не менее, он говорит только, был ли он создан. Если вы хотите приобрести блокировку, вам нужно вызвать WaitOne, а затем вызвать ReleaseMutex, чтобы освободить ее. Если вы просто хотите посмотреть, был ли вы создан Mutex, просто построить его хорошо.

Ответ 2

TheSeeker правильно.

Совет Джеффа Рихтера в Clr Via С# (p638-9) при блокировке - это создать частный объект специально для блокировки.

private Object _lock = new Object();

// usage
lock( _lock )
{
    // thread-safe code here..
}

Это работает, потому что _lock не может быть заблокирован чем-либо вне текущего класса.

EDIT: это применимо к потокам, выполняемым в рамках одного процесса. Ответ @David Mohundro правильный для блокировки между процессами.