2016-02-23 1 views
2

У нас есть этот простой код, который был преобразован с vb.net, где он не был сконструирован с использованием using/end using. Во время преобразования мы использовали using в C#.Вложенные «с помощью» сбоев .net runtime при использовании с CryptoStream

using (var memStream = new MemoryStream() { Position = 0L }) 
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv)) 
{ 
    using (var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write)) 
    { 
     // <-- here used to be try 
     string convertedValue = ConvertHexToDec(value); 
     byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line 
     // <-- here used to be catch/throw 
     cryptStream.Write(decryptBytes, 0, decryptBytes.Length); 
     cryptStream.FlushFinalBlock(); 
     cryptStream.Close(); 
    } 
    decodedVal = Encoding.ASCII.GetString(memStream.ToArray()); 
} 

Но был try/catch (см комментарии), окружающих Convert.FromBase64String(convertedValue). То, что мы не понимали, состоит в том, что value иногда приходило как обычное, не-base64-кодированное значение. Итак, когда некодированное значение попало в строку «Ошибка» - try/catch делал бизнес повторного броска. Но, когда вы смотрите на код выше, когда такое значение вызывает исключение в этой строке - .NET Runtime падает. Вот журнал событий

.NET время выполнения версия 2.0.50727.5485 - Fatal Error Execution Engine (000007FEE581600A) (80131506)

И исключение из курсе, просто нормальные

недопустимый символ в строке Base-64.

Я установил его купить удаление внутренней using

using (var memStream = new MemoryStream() { Position = 0L }) 
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv)) 
{ 
    var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write); 
    string convertedValue = ConvertHexToDec(value); 
    byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line  
    cryptStream.Write(decryptBytes, 0, decryptBytes.Length); 
    cryptStream.FlushFinalBlock(); 
    cryptStream.Close(); 
    decodedVal = Encoding.ASCII.GetString(memStream.ToArray()); 
} 

Теперь ошибка, конечно, по-прежнему, происходит, но это не врезаться времени выполнения .NET, поэтому действует нормально. Кроме того, размещение try/catch-rethrow, где оно было раньше, также предотвратило бы такой крах.

Я подозреваю, что это как-то связано с вложенными using. Внутренний using не нужен, потому что CryptoStream просто обертывает поток памяти и преобразование. И если ошибка возникает внутри фигурных скобок, она будет распространяться до try/catch преобразования сначала, а затем потока памяти.

Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборки выполняются для x64 и запускаются в пуле x64 ASP.NET? Когда приложение скомпилировано для x86 и запускается в 32-битном пуле, этого не происходит.

+0

Куда он падает? – Valentin

+0

Попробуйте переместить 'decodedVal = Encoding.ASCII.GetString (memStream.ToArray());' write after 'cryptStream.FlushFinalBlock();'. –

+0

Что значит «действует нормально»? 'using' не обрабатывает каких-либо исключенных исключений - он просто гарантирует, что одноразовый компонент будет удален, есть ли исключение или нет. –

ответ

3

Это, несомненно, ошибка во время выполнения. Поскольку вы используете чрезвычайно старую версию среды выполнения, мой совет заключается в обновлении.

Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборки выполняются для x64 и запускаются в пуле x64 ASP.NET? Когда приложение скомпилировано для x86 и запускается в 32-битном пуле, этого не происходит.

Излучения x64 и x86 были совершенно разными кодовыми базами в этой версии. Ошибка, достаточная для того, чтобы привести к сбою во время выполнения с участием странных ошибок codegen во вложенных блоках try-finally, почти наверняка будет уникальной для конкретного джиттера.

+0

здесь еще больше. Мой сотрудник не смог воспроизвести проблему. Его NDP в реестре старше моего HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ NET Framework Setup \ NDP \ v2.0.50727 \ version = 2.0.50727.5420 (мой), и его что-то вроде 47xx или 49xx - и он в порядке. Мы работаем 24/7x1.5 года при обновлении - удаление сторонних компонентов, которые не поддерживают 4+. 200 проектов - нелегко, а также разрабатывает новый материал в новых рамках. –

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