2015-06-14 2 views
2

Я использую многопоточность в моем приложениипроверка условие не выполняется при использовании многопоточности

Я создаю папку, когда папка уже не существует

if (!ExistingFolders.Contains(currentFolder)){ 
    if (lastCreatedFolder != folder) { 
      lastCreatedFolder = folder; 
      CreateNewFolder(context, siteLink, lName, fName); 
           } 
          } 

Когда есть 5 потоков, работающих параллельно, это условие не работает!! Например, все 5 потоков пытаются создать папку с именем «New» первого один становится создан, в то время как остальные бросают «Папка уже существует» ошибка как его уже создало

Как я могу проверить состояние в Это дело?

Здесь все 5 потоков работают параллельно, и условие истинно для всех тех случаях, когда, как это должно быть справедливо только в первом случае

+1

Что вы хотите сказать? –

+0

Это хорошо известная проблема. Просто обработайте ошибку. – harold

+1

Почему нитки не создают папку. Создайте его upftont в основном потоке, и после прекращения выполнения потоков удалите его, если он бесполезен. Вы нажимаете идеально синхронизацию на несколько потоков и резко понижаете их производительность, используя блокировку, чтобы решить проблему, которую они не хотят решать. Найдите способ в своей архитектуре, чтобы избежать блокировки, насколько это возможно. – Tigran

ответ

2

Это состояние гонки, и вы должны поставить механизм синхронизации для фиксации Это. например, используя ключевое слово lock, вы можете убедиться, что область кода доступна только для одного потока за раз. здесь lockobject - это объект, созданный до этих операций. например readonly const является обычным явлением.

lock(lockobject){ 

if (!ExistingFolders.Contains(currentFolder)){ 
    if (lastCreatedFolder != folder) { 
      lastCreatedFolder = folder; 
      CreateNewFolder(context, siteLink, lName, fName); 
           } 
          } 
} 
+1

Но это все еще может произойти, и другой процесс может это сделать. Это делает ее менее распространенной ошибкой, но ее все равно нужно обрабатывать. – harold

+0

Да, это правда. Мы не можем предотвратить это исключение. Даже мой обозреватель окон имеет эту проблему – n00b

2

Как я могу проверить состояние в этом случае?

С помощью синхронизации примитивной, таких как lock:

public readonly object syncRoot = new object(); 

lock (syncRoot) 
{ 
    if (!ExistingFolders.Contains(currentFolder)) 
    { 
     if (lastCreatedFolder != folder) 
     { 
      lastCreatedFolder = folder; 
      CreateNewFolder(context, siteLink, lName, fName); 
     } 
    } 
} 

Таким образом, только первый поток, чтобы достигнуть lock заявления будет удерживать блокировку, в то время как все остальные потоки ждать его, чтобы освободить Это. Как только это произойдет, все остальные потоки будут видеть, что папка уже создана.

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