Marshal.ThrowExceptionForHR 抛出 NotSupportedException
我使用以下模式将 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 方法本身的例外。
编辑:请注意,我没有直接调用任何 Stream 方法。然而,代码是在线程池线程中执行的,因此同一线程中可能还有其他使用 Stream 方法的代码。
有什么建议如何解决这个问题吗?
更新:我刚刚发现堆栈跟踪
在 System.Net.ConnectStream.get_Position()
在 System.Net.WebClient.WebClientWriteStream.get_Position()
在 System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 偏移量,Int32 原点)
属于对 Image.Save(Stream,格式)。捕获了 NotSupportedException。这些代码和平是完全独立的,但也许它们是在同一个线程池线程上执行的。
那么为什么这个异常会影响我在另一个方法中的代码呢?
im using the following pattern for translating win32 exceptions into .NET exceptions.
var result = A_KERNEL32_PINVOKE_CALL();
if (result == 0)
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
For completeness the pinvoke call is one of the following: LoadLibrary, GetProcAddress, SetWindowsHookEx.
This works well most of the time, throwing exceptions like this one:
System.ArgumentException: Argument out of range.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
But sometimes I get the following exception:
System.NotSupportedException: This Stream does not support seek operations.
at System.Net.ConnectStream.get_Position()
at System.Net.WebClient.WebClientWriteStream.get_Position()
at System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 offset, Int32 origin)
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
I can't think of a reason for this exception. Please note that the stack trace doesn't start with ThrowExceptionForHRInternal like the first exception. Hence I think this might be a exception of the ThrowExceptionForHR method itself.
EDIT: Please note that I'm not calling any Stream methods directly. However the code is executed in a thread pool thread, so there might be other code in the same thread using Stream methods.
Any suggestions how to solve this issue?
UPDATE: I just found out, that the stack trace
at System.Net.ConnectStream.get_Position()
at System.Net.WebClient.WebClientWriteStream.get_Position()
at System.Drawing.UnsafeNativeMethods.ComStreamFromDataStream.Seek(Int64 offset, Int32 origin)
belongs to a call to Image.Save(Stream, Format). There a the NotSupportedException is caught. These code peaces are completely independant, but maybe they are executed on the same thread pool thread.
So why does this exception influence my code in another method?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
现在我认为我滥用了 Marshal.ThrowExceptionForHR() 方法。我认为它不适合与 Win32 调用一起使用。我对该行为的解释是,该函数使用当前线程的上下文信息来收集有关异常的更多详细信息。 请参阅此博客了解类似问题。
就我而言,可以通过创建我自己的 ThrowExceptionForWin32ErrorCode(errorCode) 方法来解决该问题。
如果您有更好的解决方案,请继续回答。
By now I think, that I misused the Marshal.ThrowExceptionForHR() method. I suppose that it's not intended to be used with a Win32 call. My interpretation of the behavior is, that the function uses context information of the current thread to gather more details about the exception. See this blog for a similar problem.
In my case the issue can be solved by creating my own ThrowExceptionForWin32ErrorCode(errorCode) method.
Please keep answering, if you got a better solution.
我不知道为什么 ThrowExceptionForHRInternal 尝试操纵某些流。
虽然调用堆栈看起来很奇怪,但请考虑不要将流直接从 Web 响应传递到绘图函数,这在您的情况下似乎会导致异常,但首先将数据复制到内存流。这可能会让您看到原来的问题是什么(因为 ThrowExceptionForHRInternal 将不再尝试操作流失败)。
I don't know why ThrowExceptionForHRInternal tries to manipulate some stream.
While call stack looks strange, consider not passing stream directly from Web response to drawing functions which seem to cause exception in your case but copy data to memory stream first. This will likely allow you to see what original problem is (as ThrowExceptionForHRInternal will no longer fail trying to manipulate a stream).