2010-09-25 4 views
2

Хорошо. Я хочу запустить два потока. Текущий код:C# Многопоточность

public void foo() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

    public void bar() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

Оба имеют доступ к такой же список, проблема в том, что первая нитка «Foo» не отпуская замок я предполагаю; потому что «bar» запускается только тогда, когда выполняется «foo». Спасибо

+0

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

+0

читает определение семафора/мьютекса, а затем удаляет блокировку –

ответ

3

Да, вот как замок предназначен для работы.

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

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

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

private object lockObject1 = new object(); 
private object lockObject2 = new object(); 

public void foo() 
{  
    lock (lockObject1) 
    { 
     // ... 
    } 
} 

public void bar() 
{  
    lock (lockObject2) 
    { 
     // ... 
    } 
} 

В качестве альтернативы вы можете использовать тот же самый замок, но перемещать его внутри цикла, так что каждый цикл имеет возможность продолжить:

while (stopThreads == false) 
{ 
    foreach (var acc in myList) 
    { 
     lock (lockObject) 
     { 
      // process some stuff 
     } 
    } 
} 

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

Для остановки нитки я бы рекомендовал эту статью:

+0

Что относительно переменной stopThreads, она не является потокобезопасной, может быть, он получил совершенно неправильный результат. – TalentTuner

+0

@saurabh: Это может быть изменено. Или это может быть превращено в безопасное для потолка свойство. –

+0

спасибо, что сработало. – foobar

0

Проблему у вас есть то, что вы работаете с очень грубым замком. И Foo, и Bad в основном не работают одновременно, потому что тот, кто начинает сначала останавливает другой, для ЗАВЕРШЕННОГО ЦИКЛА РАБОТЫ.

Следует, однако, ТОЛЬКО ЗАКРЫТЬ, ЧТО ЭТО ПРИНИМАЕТ ВЕЩИ ИЗ СПИСКА. Foreach не работает здесь - по определению. Вы должны поставить второй список и иметь каждый поток УДАЛИТЬ ТОП-ПУНКТ (в то время как lockin), а затем работать над ним.

В основном:

  • Foreach не работает, так как оба поток будет проходить через compelte список
  • Во-вторых, замки должны быть зернистыми в том, что они запирают только при необходимости.

В вашем случае блокировка в foo будет выпущена только после завершения работы foo.

1

Поскольку вы на самом деле не задаете вопрос, я предлагаю вам прочитать учебное пособие по работе с потоками. Спецификацией .Net может быть found here. В нем представлены темы «Начало работы», «Базовая синхронизация», «Использование потоков», «Расширенная потоковая передача» и «Параллельное программирование».

Кроме того, вы блокируете «это».Msdn говорит:

В общем, избежать блокировки на общедоступном типа или экземпляров за пределами вашего кода управления. Общие конструкции lock (this), lock (typeof (MyType)) и lock ("myLock") нарушают это руководство:

  • lock (this) является проблемой, если экземпляр может быть доступен публично.

  • lock (typeof (MyType)) является проблемой, если MyType является общедоступным.

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

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