2013-07-24 2 views
2
if (runInDemoMode) 
{ 

    lock (this) 
    { 
     //Initalization of tables 
     dCreator.createInitialTables(); 
     SetupPlugins(); 
     AutoConfigure(database); 

     //Simulator     
     sim.processSimulatedData(); 
    } 
    return; 

} 

В идеале я хотел бы иметь инициализированные таблицы (один раз), а затем симулятор работает снова и снова. Так как у меня есть 3 встроенных метода для таблиц, которые также находятся под замком, они все время становятся все активнее, и я не хочу этого делать.C# lock (this) method

Любые предложения относительно того, как я могу гарантировать, что если я нахожусь в режиме демонстрации, я могу инициализировать таблицы один раз, а затем запускать симулятор снова и снова.

Жизненно важно, чтобы таблицы были инициализированы до запуска симулятора, иначе это не сработает.

+4

Вы должны заблокировать частный объект, а не 'this' (общий шаблон -' private readonly object _createTableLockObj = new object(); '). Если другой класс сделал «lock (yourClass)», это также помешало бы вашему коду войти в ваш замок. Используя закрытый объект для блокировки блокировки, можно использовать только одну функцию. –

+4

[Не блокировать 'this'] (http://stackoverflow.com/q/251391/1968) –

+1

Создайте статический volatile bool, который установлен в true после инициализации. Только если этот bool является ложным, вызовите процедуру инициализации таблицы –

ответ

2

Использование блокировки здесь, возможно, не самая лучшая идея. Вы должны рассмотреть, просто имея переменную с именем initialized, которая является логическим значением, первоначально установленным на false. Если для этого кода установлено значение false, запустите блок инициализации кода и установите переменную в true. Затем, в следующий раз, когда этот код будет достигнут, ваш ветвь будет оцениваться до false, а код инициализации снова не будет запущен.

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

0

Другие отметили проблему с вашим шаблоном блокировки, и это трудно ответить, не видя остальную часть вашего кода, но вы можете легко добавить bool, чтобы помочь в этом.

bool tablesInitialized = false; 

if (runInDemoMode) 
{ 

    lock (this) 
    { 
     if (!tablesInitialized) 
     { 
      //Initalization of tables 
      dCreator.createInitialTables(); 
      SetupPlugins(); 
      AutoConfigure(database); 

      tablesInitialized = true; 
     } 

     //Simulator     
     sim.processSimulatedData(); 
    } 
    return; 

} 
0

блокировка будет поддерживать код внутри него только в нескольких потоках одновременно.

Что вам нужно, это переменная инициализации в вашем классе или на любом уровне, соответствующем (пока неясно, где вам это нужно), что позволяет вашему коду знать, что он уже инициализирован.

bool isInitialized = false; 

... 

if (runInDemoMode) 
{ 

    if (!isInitialized) 
    { 
     //Initalization of tables 
     dCreator.createInitialTables(); 
     SetupPlugins(); 
     AutoConfigure(database); 

     //Simulator     
     sim.processSimulatedData(); 

     isInitialized = true; 
    } 
    return; 

} 
1

Возможно, вы ищете двойную блокировку.

private static readonly object _locker = new object(); 

public SomeClass(bool runInDemoMode) 
{ 
    if (runInDemoMode) 
    { 
     lock (_locker) 
     { 
      if (runInDemoMode) 
      { 
       //Initalization of tables 
       dCreator.createInitialTables(); 
       SetupPlugins(); 
       AutoConfigure(database); 

       //Simulator     
       sim.processSimulatedData(); 
      } 
     } 
    } 
} 

Вероятно, было бы лучше, чтобы абстрагироваться эта логика в какой-то DemoInitializer класса, который может самостоятельно установку и демонтаж приложения.