Информация об изменениях

Сообщение Re: Чтение и запись коллекций из разных потоков от 23.01.2015 12:08

Изменено 23.01.2015 12:10 artelk

Здравствуйте, zoom-zoom, Вы писали:

ZZ>День добрый!

ZZ>Немного запутался с потоками. Делаю следующее:

ZZ>
ZZ>    private void button2_Click(object sender, EventArgs e) 
ZZ>    { 
ZZ>        lock (_object) 
ZZ>        { 
ZZ>            MyStruct ms = MyClass.mylist[2]; 
ZZ>            ms.var1 = 0; 
ZZ>            MyClass.mylist[2] = ms; 
ZZ>        } 
ZZ>    } 
ZZ>



ZZ>Задача в том, чтобы обновляя в SortedList данные, ничего не потерялось бы и все переменные mylist получили бы нужные значения.

ZZ>Но есть нюанс в приведенном примере. При работе с lock иногда может зависнуть код в строке с lock в button2_Click. Если убрать lock везде или где-то, то может быть случай, когда запись идет некооректно в mylist из-за прерывания потока и обновления данных в другом потоке. Как можно еще обезопасить, если не lock, чтобы не было зависаний?

В button2_Click можно сделать Monitor.TryEnter(_object) и, если удалось, выполнить эти три строчки прямо по месту и потом сделать Monitor.Exit(_object).
Если блокировку захватить не удалось — запустить отдельный поток (или добавить задание в ThreadPool) и уже оттуда сделать все с обычным локом.
Re: Чтение и запись коллекций из разных потоков
Здравствуйте, zoom-zoom, Вы писали:

ZZ>День добрый!

ZZ>Немного запутался с потоками. Делаю следующее:

ZZ>
ZZ>    private void button2_Click(object sender, EventArgs e) 
ZZ>    { 
ZZ>        lock (_object) 
ZZ>        { 
ZZ>            MyStruct ms = MyClass.mylist[2]; 
ZZ>            ms.var1 = 0; 
ZZ>            MyClass.mylist[2] = ms; 
ZZ>        } 
ZZ>    } 
ZZ>



ZZ>Задача в том, чтобы обновляя в SortedList данные, ничего не потерялось бы и все переменные mylist получили бы нужные значения.

ZZ>Но есть нюанс в приведенном примере. При работе с lock иногда может зависнуть код в строке с lock в button2_Click. Если убрать lock везде или где-то, то может быть случай, когда запись идет некооректно в mylist из-за прерывания потока и обновления данных в другом потоке. Как можно еще обезопасить, если не lock, чтобы не было зависаний?

В button2_Click можно сделать Monitor.TryEnter(_object) и, если удалось, выполнить эти три строчки прямо по месту и потом сделать Monitor.Exit(_object).
Если блокировку захватить не удалось — запустить отдельный поток (или добавить задание в ThreadPool) и уже оттуда сделать все с обычным локом.