http://en.cppreference.com/w/cpp/atomic/memory_order имеет хороший пример внизу , который работает только с memory_order_seq_cst
. По существу, memory_order_acq_rel
обеспечивает порядок чтения и записи относительно атомарной переменной, в то время как memory_order_seq_cst
обеспечивает порядок чтения и записи глобально. То есть последовательно согласованные операции видны во всех потоках в одном и том же порядке.
Пример сводится к следующему:
bool x= false;
bool y= false;
int z= 0;
a() { x= true; }
b() { y= true; }
c() { while (!x); if (y) z++; }
d() { while (!y); if (x) z++; }
// kick off a, b, c, d, join all threads
assert(z!=0);
Операции над z
защищены двумя атомными переменными, а не одной, поэтому вы не можете использовать семантику acqu-release для принудительного выполнения этого z
всегда увеличивается.
Для .Net Framework 4.5 и выше вы можете использовать свойство Exception.HResult
:
int hr = ex.HResult;
Для более старых версий вы можете использовать Marshal.GetHRForException
, чтобы вернуть результат HResult, но этот имеет серьезные побочные эффекты и не рекомендуется :
int hr = Marshal.GetHRForException(ex);
Помогает ли свойство CanRead
в этом случае?
т.е. вызовите CanRead
, если это вернет истину, вызовите Read ()
Были ли вы проанализированы какие-либо из этих случаев? Я предполагаю, что метод отражения не так уж и медленен, особенно по сравнению со всеми другими работами, которые ваше приложение будет выполнять, и как часто это исключение может возникать.
Если это окажется узким местом, вы можете изучить кэширование некоторых операций отражения или сгенерировать динамический IL для извлечения свойства.