2011-04-04 115 views
1

im使用以下模式将win32异常转换为.NET异常。Marshal.ThrowExceptionForHR引发一个NotSupportedException

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中)

我想不出一个理由的F或这个例外。请注意,堆栈跟踪不像第一个异常那样以ThrowExceptionForHRInternal开始。因此我认为这可能是ThrowExceptionForHR方法本身的一个例外。

编辑:请注意,我没有直接调用任何流方法。但是,代码是在线程池线程中执行的,所以在使用Stream方法的同一线程中可能有其他代码。

有什么建议如何解决这个问题?

更新:我刚刚发现,该堆栈跟踪

在System.Net.ConnectStream.get_Position()

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

在System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64的偏移量,的Int32原点)

属于到Image.S呼叫ave(Stream,Format)。有一个NotSupportedException被捕获。这些代码peaces是完全独立的,但也许它们是在同一个线程池线程上执行的。

那么为什么这个异常会影响我的代码在另一种方法?

+0

当你得到NotSupportedException时,你能告诉我们你从Marshal.GetHRForLastWin32Error()得到什么值吗? – HABJAN 2011-04-04 15:35:53

+0

我试图得到这个值,但这个问题很难重现。 – 2011-04-04 16:24:11

+0

hresult是-2147024809(Win32 /无效参数)。有时候会抛出一个ArgumentException,有时候是一个NotSupportedException。 (由于方法SetWindowsHookEx(path)。处理ArguementException) – 2011-04-07 08:43:01

回答

0

我不知道为什么ThrowExceptionForHRInternal尝试操纵某些流。

虽然调用堆栈看起来很奇怪,但考虑不要直接从Web响应传递流,直接将绘图函数传递给您的情况,但这会在您的情况下导致异常,但会首先将数据复制到内存流中。这可能会让你看到什么原始问题(因为ThrowExceptionForHRInternal将不再失败,试图操纵一个流)。

+0

流方法调用不是我的代码。我不知道如何影响这一点。 – 2011-04-04 16:17:13

1

现在我想,我滥用Marshal.ThrowExceptionForHR()方法。我想这并不打算用于Win32调用。我对行为的解释是,函数使用当前线程的上下文信息来收集有关异常的更多细节。 See this blog有类似的问题。

在我的情况下,问题可以通过创建我自己的ThrowExceptionForWin32ErrorCode(errorCode)方法来解决。

如果你有更好的解决方案,请继续回答。

相关问题