mov еах, dword ptr [ebp-64] ; скопировать со стека в регистр
inc еах ; увеличить значение в регистре
mov dword ptr [ebp-64], еах ; скопировать из регистра на стек
// Код на С#:
int n = . . .;
if (Interlocked.CompareExchange(ref n, 1, 0) = 0) ( // заменить 0 на 1
// ...выполнить некоторые операции
}
// инструкции на языке ассемблера х8б:
mov еах, 0 ;
mov edx, 1 ;
lock cmpxchg dword ptr [ebp-64], edx ;
test eax, eax ;
i
jnz not__taken
// ... выполнить некоторые операции
not_taken:
List - внутренне хранит массив и отслеживает логический размер списка и размер поддерживающего массива. Добавление элемента является либо простым случаем установки очередного значения в массиве, либо (если массив уже заполнен) копированием существующего содержимого в новый массив большего размера (обычно в два раза, т.е. происходит удвоение, но это недокументированно) и затем установки в нем значения. Сложность O(1) или O(n) в зависимости от того требуется ли копирование значений. Удаление элемента из List требует копирования расположенных за ним элементов на позицию назад, поэтому сложность составляет O(n-k), где k - индекс удаляемого элемента. По индексу RemoveAt() удалять значительно быстрее чем по значению Remove(), т.к. во втором случае происходит сравнение каждого элемента где бы он не находился сложность O(n).
**Массивы** - самый низкий уровень коллекций в .Net. Унаследованы от System.Array, и они единственные имеют прямую поддержку в среде CLR. Массивы всегда изменяемы в терминах своих элементов, но всегда фиксированы в терминах своих размеров.
Foreach для массива использует его свойство Length и индексатор массива, а не создает объект итератора.
**LinkedList** - связанный список, каждый элемент которого имеет ссылку на предыдущий и следующий элемент. Быстро можно удалять, вставлять новые элементы, т.к. происходит только изменение ссылок на соседних узлах. Проход по коллекции тоже эффективен, но разумеется нет индекса.
**Dictionary** - подобно List хранит свои элементы в массиве, со всеми вытекающими по вставке и увеличению размера последствиями. Для реализации эффективного поиска использует хештаблицу. Можно либо применять стандартные функции хеширования и эквивалентности внутри самих объектов ключей, либо передать реализацию IEqualityComparer в аргументе конструктора. Ключи должны быть уникальными, но хешкоды могут совпадать, что снижает эффективность поиска. Словарь даст отказ, если ключи являются изменяемыми и меняют свои хешкоды после того, как были вставлены в словарь. Внутри этого словаря нет гарантии порядка следования элементов, так что рассчитывать на него нельзя. Вставка происходит на основе ключа (что-то вроде индекса), а не последовательности заполнения словаря.
**ReadOnlyDictionary<,>** - просто оболочка, которая скрывает все изменяемые операции за явной реализацией интерфейса, и генерирует исключение если они все же вызываются. Но если лежащая в основе коллекция (та что передается конструктору) модифицируется, то модификации будут видны через оболочку.
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
//p.StartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
int lcid = GetSystemDefaultLCID();
var ci = System.Globalization.CultureInfo.GetCultureInfo(lcid);
var page = ci.TextInfo.OEMCodePage;
p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding(page);
p.Start();
try
{
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.StandardInput.AutoFlush = true;
p.OutputDataReceived += (s, e) => { ... }
p.ErrorDataReceived += (s, er) => { ... }
while (true)
{ // "\x3" - Ctrl+C
if (p.HasExited == true) { break; }
p.StandardInput.WriteLine( ... );
}
}
catch (Exception)
{
...
}