//For me it's the best way to look for the value of a spezific column
int seekValue = 5;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var columnValue = Convert.ToInt32(row.Cells["ColumnName"].Value);
if (columnValue == seekValue)
{
dataGridView1.CurrentCell = row.Cells[0];
}
}
Изменение, которое упомянул модификатор доступа
counter
кpublic volatile
Как другие люди, это самостоятельно не на самом деле безопасно вообще. Точка volatile
- то, что несколько потоков, работающих на нескольких центральных процессорах, могут и быть данные кэша и переупорядочивать инструкции.
, Если это не volatile
, и ЦП инкременты значение, затем ЦП B не может на самом деле видеть, что увеличенное значение до некоторое время спустя, который может вызвать проблемы.
, Если это volatile
, это просто гарантирует, чтобы эти два центральных процессора видели те же данные одновременно. Это не останавливает их вообще от чередования их чтений и операций записи, который является проблемой, которой Вы стараетесь избегать.
lock(this.locker) this.counter++
;
Это безопасно сделать (если Вы еще помните к lock
везде, что Вы получаете доступ this.counter
). Это препятствует тому, чтобы любые другие потоки выполнили любой другой код, который охраняют locker
. Используя блокировки также, предотвращает проблемы переупорядочения мульти-ЦП как выше, который является большим.
проблема, блокировка является медленной, и если Вы снова используете locker
в некотором другом месте, которое действительно не связано тогда, можно закончить тем, что блокировали другие потоки ни по какой причине.
Interlocked.Increment(ref this.counter);
Это безопасно, поскольку это эффективно делает чтение, инкремент, и пишет в 'одном хите', который не может быть прерван. Из-за этого это не будет влиять ни на какой другой код, и Вы не должны помнить блокировать в другом месте также. Это также очень быстро (как MSDN заявляет на современных центральных процессорах, это - часто буквально единственная инструкция по ЦП).
я не совсем уверен однако, если он обходит другие центральные процессоры, переупорядочивающие вещи, или если также необходимо объединиться энергозависимый с инкрементом.
InterlockedNotes:
Как [1 111] не предотвращает эти виды проблем многопоточности, для чего это? Хороший пример говорит, что у Вас есть два потока, тот, который всегда пишет в переменную (говорят queueLength
), и тот, который всегда читает из той же самой переменной.
, Если queueLength
не энергозависимо, поток A может записать пять раз, но распараллелить B, может видеть те записи, как откладываемые (или даже потенциально в неправильном порядке).
решение для А состояло бы в том, чтобы заблокировать, но Вы могли также использовать энергозависимый в этой ситуации. Это гарантировало бы, что поток B будет всегда видеть самую актуальную вещь, которые распараллеливают A, записал. Обратите внимание однако, что эта логика [только 1 117] работы, если у Вас есть писатели, которые никогда не читали, и читатели, которые никогда не пишут, и , если вещь Вы пишете, являются атомарным значением. Как только Вы делаете единственный read-modify-write, необходимо перейти к Взаимно блокируемым операциям или использовать Блокировку.
РЕДАКТИРОВАНИЕ: , Как отмечено в комментариях, в эти дни я рад использовать Interlocked
для случаев единственная переменная , где это , очевидно хорошо. Когда это станет более сложным, я все еще вернусь к блокировке...
Используя volatile
не поможет, когда необходимо увеличить - потому что чтение и запись являются отдельными инструкциями. Другой поток мог изменить значение после чтения, но перед обратной записью.
Лично я почти всегда просто блокирую - легче разобраться способом, который является , очевидно прямо или, чем энергозависимость или, чем Взаимно блокируется. Инкремент. Насколько я заинтересован, многопоточность без блокировок настоящая экспертов по поточной обработке, из которых я не тот. Если Joe Duffy и его команда создают хорошие библиотеки, которые параллелизируют вещи без такой же блокировки как что-то, что я создал бы, это невероятно, и я буду использовать его в heartbeat - но когда я сделаю поточную обработку меня, я пытаюсь сохранить его простым.
" volatile
" не заменяет Interlocked.Increment
! Это просто удостоверяется, что переменная не кэшируется, но используется непосредственно.
Постепенное увеличение переменной требует на самом деле трех операций:
Interlocked.Increment
выполняет все три части как единственную атомарную операцию.
Взаимно блокируемые функции не блокируют. Они являются атомарными, означая, что они могут завершиться без возможности контекстного переключения во время инкремента. Таким образом, нет никакого шанса мертвой блокировки, или ожидать.
я сказал бы, что необходимо всегда предпочитать его блокировке и инкременту.
Энергозависимый полезно, если Вам нужны записи в одном потоке, который будет считан в другом, и если Вы хотите, чтобы оптимизатор не переупорядочил операции на переменной (потому что вещи происходят в другом потоке, который оптимизатор не знает о). Это - ортогональный выбор к тому, как Вы увеличиваете.
Это - действительно хорошая статья, если Вы хотите читать больше о коде без блокировок и правильном способе приблизиться к записи ее
блокировка (...) работает, но может заблокировать поток и могла вызвать мертвую блокировку, если другой код использует то же, привязывает несовместимый путь.
Взаимно блокировался.* корректный способ сделать это... намного меньше служебный, поскольку современные центральные процессоры поддерживают это как примитив.
энергозависимый самостоятельно не корректно. Поток, пытающийся получать и затем записывать измененное значение обратно, мог все еще конфликтовать с другим потоком, делающим то же.
Я провел несколько тестов, чтобы увидеть, как на самом деле работает теория: kennethxu.blogspot.com/2009/05/interlocked-vs-monitor-performance.html . Мой тест был больше ориентирован на CompareExchnage, но результат для Increment был аналогичным. Взаимоблокировка не требуется быстрее в среде с несколькими процессорами. Вот результат теста для Increment на сервере с 16 процессорами, которому 2 года. Помните, что тест также включает в себя безопасное чтение после увеличения, что типично в реальном мире.
D:\>InterlockVsMonitor.exe 16
Using 16 threads:
InterlockAtomic.RunIncrement (ns): 8355 Average, 8302 Minimal, 8409 Maxmial
MonitorVolatileAtomic.RunIncrement (ns): 7077 Average, 6843 Minimal, 7243 Maxmial
D:\>InterlockVsMonitor.exe 4
Using 4 threads:
InterlockAtomic.RunIncrement (ns): 4319 Average, 4319 Minimal, 4321 Maxmial
MonitorVolatileAtomic.RunIncrement (ns): 933 Average, 802 Minimal, 1018 Maxmial