2012-09-25 14 views
6

Bir Windows çalışma zamanı türü bir COM hatası ortaya çıkarırsa. NET bu hatayı sık sık (veya her zaman?) Bir Exception örneğine sığacak gibi görünüyor. Hata iletisi COM HRESULT hata kodunu içerir. Yeni Kriptografik API'yi AES-CBC ile kullanırken, örneğin bir yanlış arabellek uzunluğu, "Sağlanan kullanıcı arabelleği, istenen işlem için geçerli değil." (Exception from HRESULT: 0x800706F8) "mesajıyla birlikte bir Exception sonucunu verir.İstisna ile sonuçlanan WinRT istisnaları nasıl ele alınır?

Eh, nasıl bu istisnalar işlemek gerekiyor? Ne tür bir istisna olduğunu öğrenmek için istisnadan HRESULT kodunu okur muyuz? Klasik .NET'te, kriptografik hataları diğer hatalardan ayırt etmek için kullanabileceğim bir CryptographicException alırdım. Anlamadığım

Başka bir şey Microsoft kod kalite kuralları bir gerektiği ifade olmasıdır asla atış İstisna ama her zaman türetilmiş türleri. Bunun nedeni, hiç kimse OutOfMemoryException gibi daha ölümcül istisnaları yakalayan genel Exception'u yakalamaya zorlanmamalıdır. Başka bir kural da, kütüphanelerde asla asla Exceptio n yakalanmaması gerektiğini söylüyor. Windows Mağazası uygulamalarında veya WinRT kitaplıklarında Exception yakalamak zorunda kalırsak bu politikaları nasıl izleyebiliriz? Bu arada

: Clemens Vasters shows in his blog how we can catch Exception while avoiding to catch fatal exception. Exception'un artık kötü bir kod olmadığını anlıyorum.

+0

, listelenen "ölümcül" istisnalar birçok yönetilen kod tarafından yakalandı edilemez. Özellikle, 'StackOverflowException', ancak AV'lerin de yakalanamayacağı konusunda kesin olarak eminim (her ikisi de tabii ki yerel koda yakalanabilir, ancak bunu yapmak tehlikelidir). Ayrıca, _appear_ ölümcül bazı istisnalar aslında olmayabilir. Örneğin, belirli bir arabellekteki boşluk bittiğinde, birçok COM bileşeni 'E_OUTOFMEMORY' döndürür. Bu HRESULT bir OutOfMemoryException olarak çevrilecektir, ancak sürecin tüm adres alanını tükettiği anlamına gelmez. –

cevap

4

Exception yakalamak, HRESULT özelliğini açarak belirli hataları işlemek ve hata "beklenmeyen" olduğunda yeniden Exception yeniden atmak mümkündür. Örneğin,

try 
{ 
    // ... 
} 
catch (Exception ex) 
{ 
    switch (ex->HResult) 
    { 
    case E_INVALID_USER_BUFFER: // 0x800706f8 
     // handle invalid buffer case... 
     break; 
    default: 
     // Unexpected exception; re-throw: 
     throw; 
    } 
} 

(ı geçersiz tampon sağlayarak daha bir çalışma zamanı hatası daha bir mantık hatası gibi geliyor dikkat ediyorum, bu yüzden bu özel durum gerçekten yakalanmış gerekip gerekmediğini merak ediyorum.)

Alternatif olarak, daha genel bir çözüm, bilinen HRESULT'lar için Exception'u işleyen bir işlev veya işlev kümesi yazmak ve daha özel bir istisna atar. Örneğin, bu yaklaşımların her ikisi de hem C++ hem de C# 'da eşit derecede iyi çalışır. mutlaka Exception platform veya diğer bileşenleri tarafından doğrudan atılır böyle değildir

Not. Windows Runtime ABI katmanında istisna yoktur: Tüm hatalar HRESULT tarafından ABI sınırında raporlanır. CLR, bir avuç bilinen bilinen HRESULT'ı daha özel istisna türlerine çevirir, ancak genel bir çeviri yapamaz. bağlantılı blog girdisi bakımından

+0

Teşekkürler James. Bu geçersiz arabellek HRESULT yakalarken benim yaklaşımım oldu. .NET programcılarının şimdi HRESULTS ile uğraşması gereken biraz garip buluyorum. Temperlenmiş veya basit bir şekilde kırpılmış olabilecek geçersiz verilerin şifresini çözmeye çalışırken kolayca geçersiz bir tampon alırsınız. Şifrelenmiş verileri doğru uzunlukta kontrol etmek neredeyse imkansızdır çünkü bu, kullanılan algoritmaya ve anahtara bağlıdır. Kullanılan blok boyutunu bulmak için zaten yeterince zor.Geçersiz arabellek hatasını yakalamak, geçersiz verilerin kullanıcı dostu bir şekilde ele alındığından emin olmak için çok önemlidir. –

+0

Ah, o zaman benim hatam. Tamponun geçersiz olduğunu yanlış anladım. Haklısınız, bu tür bir hataya dikkat etmek iyi bir fikir :-) –