Lock () в статическом методе - PullRequest
       1

Lock () в статическом методе

19 голосов
/ 25 октября 2010

У меня есть многопоточное приложение, которое пишет в файл настроек XML статическим методом.Я хочу избежать того, чтобы файл обновлялся дважды одновременно (вызывая исключения доступа / записи).

Как мне это сделать?

Это не работает:

namespace Program
{
    public class Settings
    {
        private static void SetSettingsValue (string settings, string value)
        {
            // make this thread safe to avoid writing to a locked settings xml file
            lock (typeof(Settings))
            {
                //write data to xml file
            }
        }
    }
}

Ответы [ 2 ]

40 голосов
/ 25 октября 2010

Вы должны создать отдельный статический объект блокировки и использовать его. НЕ ИСПОЛЬЗУЙТЕ СТРУНУ! Строки автоматически интернируются, и будет только один экземпляр каждой программно объявленной строки, поэтому вы не можете гарантировать эксклюзивный доступ к блокировке.

Вы должны сделать это:

public class A {
    private static Object LOCK = new Object();

    private static void foo() {
        lock(LOCK) {
            // Do whatever
        }
    }
}

(Синтаксис может быть неправильным; я в основном Java-человек, но к C # применяются те же правила блокировки и интернирования строк)

Ключевое слово lock обеспечивает блокировку взаимного исключения: только один поток может заблокировать любой конкретный объект одновременно. Если второй поток вызывает foo, он будет блокироваться до тех пор, пока первый поток не выйдет из блока блокировки.

Принять домашние сообщения: для статического метода блокировки частной статической переменной. Не блокируйте строки или typeof (...), потому что вы не можете гарантировать, что никто другой не использует этот объект. Всегда блокируйте объект, который, как вы знаете, никто не трогает, делая его закрытым и создавая новый.

33 голосов
/ 25 октября 2010

Концепция lock () заключается в использовании существующего объекта, на который он может ссылаться и который используется для контроля предоставления доступа.

static object SpinLock = new object();

lock(SpinLock)
{
   //Statements
}

Когда выполнение покидает блок lock (), ссылка освобождается, и любые другие потоки, ожидающие выполнения блока кода, могут продолжаться (конечно, по одному).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...