2012-06-29 4 views
1

Это мой первый вопрос в этом форуме, поэтому я надеюсь, что понятно:Ошибка инициализации нити (Закрытие?)

I'm с помощью Visual Studio 2010 RTM Программирование в C#

Конструктор класса , которые преобразуются в поток, всегда принимают значения из последнего словаря. Я не знаю, что я делаю неправильно, кто-то?

Кодекс работы это не распространяется:

Dictionary<string, Queue<string>> colas; 

    public DataDispatcher(Dictionary<string, int> lectoras, ReadEventHandler callback) 
    { 
     colas = new Dictionary<string, Queue<string>>(); 

     foreach (KeyValuePair<string, int> pair in lectoras) 
     { 
      colas.Add(pair.Key, new Queue<string>>()); 

      Thread hilo = new Thread(
       () => new ReadHandler(pair.Value, colas[pair.Key], callback)); 

      hilo.Name = "Hilo-" + hilo.ManagedThreadId.ToString(); 

      hilo.Start(); 
     } 
    } 

Вместо этого код работает отлично:

Dictionary<string, Queue<string>> colas; 

    public DataDispatcher(Dictionary<string, int> lectoras, ReadEventHandler callback) 
    { 
     colas = new Dictionary<string, Queue<string>>(); 

     foreach (KeyValuePair<string, int> pair in lectoras) 
     { 
      Queue<string> qs = new Queue<string>(); 

      colas.Add(pair.Key, qs); 

      int jaula = pair.Value; 

      Thread hilo = new Thread(
       () => new ReadHandler(jaula, qs, callback)); 

      hilo.Name = "Hilo-" + hilo.ManagedThreadId.ToString(); 

      hilo.Start(); 
     } 
    } 
+0

Определить «работы» и «не работает». Что ты имеешь в виду? – Oded

+2

Какая ошибка вы получаете? – Mayank

ответ

2

Это очень распространенная ошибка, называемая «захват переменной цикла» или «закрытие над переменная ".

foreach (KeyValuePair<string, int> pair in lectoras) 
{ 
    colas.Add(pair.Key, new Queue<string>>()); // here 'pair' is OK 

    var copy = pair; // this is the fix, make a new 'copy' for each thread 

    Thread hilo = new Thread(
     () => new ReadHandler(copy.Value, colas[copy.Key], callback)); 
} 

Вы начинали число потоков с использованием всех же переменной pair. Эта «захваченная» переменная ведет себя как параметр «проход по ссылке». К моменту начала Threads запускается foreach(), и все они используют последний элемент.

На боковой ноте вы, вероятно, не должны использовать голые нити для этого. Используйте объекты ThreadPool или Task из TPL.

+0

Большое спасибо за sugestion! Я буду реорганизовать выполнение задач .. – Guillermo

1

Да. Вы являетесь жертвой так называемой «Захваченной переменной». Здесь снимается pair. Смотрите эту статью: http://blog.sluu.org/captured-variable/

Edit: Я также заметил ошибку синтаксиса в первом фрагменте OP в: colas = new Dictionary<string, Queue<string>>(); Там в дополнительный знак больше в этой линии.

+0

В первом фрагменте захвата «пара» захвачена, а не только клавиша. –

+0

О, мой плохой! Я не видел ссылку 'pair.Value'. Я только видел «пар.Кей», поэтому я только упомянул «пар.Кей». Будет редактировать! Благодаря! :-) –

+0

Ошибка синтаксиса была ошибкой копирования, извините! – Guillermo

Смежные вопросы