Marshal.ThrowExceptionForHR создает исключение NotSupportedException - PullRequest
2 голосов
/ 04 апреля 2011

я использую следующий шаблон для перевода исключений win32 в исключения .NET.

var result = A_KERNEL32_PINVOKE_CALL();
if (result == 0)
{
   Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}

Для полноты вызова pinvoke является одним из следующих: LoadLibrary, GetProcAddress, SetWindowsHookEx.

В большинстве случаев это работает хорошо, генерируя такие исключения:

System.ArgumentException: Аргумент вне диапазона.

в System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal (Int32 errorCode, IntPtr errorInfo)

Но иногда я получаю следующее исключение:

System.NotSupportedException: этот поток не поддерживает операции поиска.

в System.Net.ConnectStream.get_Position ()

в System.Net.WebClient.WebClientWriteStream.get_Position ()

в System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek Int64 (смещение, происхождение Int32)

в System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal (Int32 errorCode, IntPtr errorInfo)

Я не могу придумать причину этого исключения.Обратите внимание, что трассировка стека не начинается с ThrowExceptionForHRInternal, как первое исключение.Поэтому я думаю, что это может быть исключением из самого метода ThrowExceptionForHR.

РЕДАКТИРОВАТЬ: Обратите внимание, что я не вызываю какие-либо потоковые методы напрямую.Однако код выполняется в потоке пула потоков, поэтому в этом же потоке может использоваться другой код с использованием потоковых методов.

Есть предложения по решению этой проблемы?

ОБНОВЛЕНИЕ: Я только что нашелчто трассировка стека

в System.Net.ConnectStream.get_Position ()

в System.Net.WebClient.WebClientWriteStream.get_Position ()

вSystem.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek (смещение Int64, происхождение Int32)

относится к вызову Image.Save (поток, формат).Там ловится исключение NotSupportedException.Эти кодовые блоки полностью независимы, но, возможно, они выполняются в том же потоке пула потоков.

Так почему это исключение влияет на мой код в другом методе?

Ответы [ 2 ]

2 голосов
/ 07 апреля 2011

Сейчас я думаю, что я неправильно использовал метод Marshal.ThrowExceptionForHR ().Я полагаю, что он не предназначен для использования с вызовом Win32.Моя интерпретация поведения состоит в том, что функция использует контекстную информацию текущего потока, чтобы собрать больше деталей об исключении. См. Этот блог для аналогичной проблемы.

В моем случае проблему можно решить, создав мой собственный метод ThrowExceptionForWin32ErrorCode (errorCode).

Пожалуйста, продолжайте отвечать, если у вас есть лучшее решение.

0 голосов
/ 04 апреля 2011

Я не знаю, почему ThrowExceptionForHRInternal пытается манипулировать каким-то потоком.

Хотя стек вызовов выглядит странно, не следует передавать поток напрямую из Web-ответа функциям рисования, которые в вашем случае вызывают исключение, но сначала скопируйте данные в поток памяти. Это, вероятно, позволит вам увидеть, в чем заключается исходная проблема (поскольку ThrowExceptionForHRInternal больше не будет пытаться манипулировать потоком).

...