Tom*_*sar 6 c# wpf service image
我正面临着一个我无法解决的问题或google解决方案.
我正在运行加载或保存图像和使用BitmapEncoder或BitmapDecoder类的服务.一段时间后(取决于我保存/加载图像的频率)服务拒绝保存/加载图像.首先,我在事件日志中看到警告
堆分配失败
我用Google搜索了它的意思,它与Windows服务所拥有的有限数量的GDI对象有关.它可以修改注册表以增加这些对象的数量,但它不是很好的解决方案,我认为它也不适合我.
保存时,我的代码会抛出堆栈跟踪异常
Error while storing image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Threading.Dispatcher..ctor()
at System.Windows.Threading.DispatcherObject..ctor()
at System.Windows.Media.Imaging.BitmapEncoder..ctor(Boolean isBuiltIn)
at Imaging.TiffReadWrite.Save(String filename, Image img)
Run Code Online (Sandbox Code Playgroud)
并在加载时
Error while loading image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully
at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks)
at System.Windows.Threading.Dispatcher..ctor()
at System.Windows.Threading.DispatcherObject..ctor()
at System.Windows.Media.Imaging.BitmapDecoder..ctor(Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId)
at Imaging.TiffReadWrite.Load(String filename)
Run Code Online (Sandbox Code Playgroud)
我保存图像的代码如下:
public static void Save(string filename, BitmapSource img)
{
using (FileStream stream = new FileStream(filename, FileMode.Create))
{
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.None;
BitmapFrame frm = BitmapFrame.Create(img);
encoder.Frames.Add(frm);
encoder.Save(stream);
}
}
Run Code Online (Sandbox Code Playgroud)
和加载图像看起来像:
public static BitmapSource Load(string filename)
{
BitmapSource resultImage = null;
using (Stream imSource = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var decoder = new TiffBitmapDecoder(imSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
resultImage = decoder.Frames[0];
}
return resultImage;
}
Run Code Online (Sandbox Code Playgroud)
因此,服务拒绝保存/加载图像.我可以尝试/捕获此异常,以便服务可以继续运行,但不能保存/加载任何图像.有时在第一次出现此异常后,可以保存/加载一些图像,一段时间后不执行保存/加载.
我解决此问题的唯一方法是不在服务中运行此代码,而是在应用程序中运行.然后它运行得很好,但这不是我正在寻找的解决方案.如果有人有任何更好的建议,请告诉我.
有一些类似的帖子(异常的堆栈跟踪大致相同)实际上没有解决:
操作成功完成
这个神秘的消息缩小了 HwndWrapper 构造函数中失败的确切代码范围。WPF 在GetStockObject pinvoke 声明中存在错误。它的SetLastError = true属性是错误的,GetStockObject()实际上不会产生错误代码。您会看到错误代码 0 的描述,“没有出错”。
GetStockObject() 是一个 winapi 函数,如果获得正确的参数,它永远不会失败。库存对象是预先分配的并且永远不会释放。您有非常有力的证据表明进程状态已彻底损坏。在事件日志中看到“堆分配失败”消息肯定是这种痛苦的一部分。
如果您不知道什么可能导致这种损坏,机器已知良好,具有可靠的 RAM,您没有运行任何危险的本机代码,并且机器没有运行任何其他可能损坏桌面堆的服务,那么您唯一的选择是创建崩溃进程的小型转储。致电 Microsoft 支持人员,他们可以追踪 GetStockObject() 失败的踪迹。请注意,您必须穿过第一个支撑层,这些支撑层会告诉您更换机器:)