ASP.NET在创建BitmapImage时抛出Win32Exception,找不到指定的文件

时间:2012-01-24 23:03:23

标签: asp.net iis bitmapimage

我一直在开发一个图书浏览网站,它可以拍摄相当大的图像(超过7700万像素)并在投放图像之前将其缩小。它基本上做了以下算法:

  1. 如果已缓存请求的图书,请提供缓存的图片。
  2. 如果图书没有被缓存,请将图书添加到我们的图书缓存线程池中。
  3. 图书缓存线程池将每本图书的页面添加到我们的页面缓存线程池中。
  4. 页面缓存线程池通过将图像反复减半来缓存图像(位于我们LAN上的服务器上),直到我们将图像的缓存版本减少2x,4x,8x,16x,32x和64x
  5. 以下是将单个图像减半的代码。注意使用BitmapImage:

    Private Shared Function HalveImage(ByVal baseImagePath As String, ByVal baseWidth As Integer, ByVal baseHeight As Integer, ByVal newImagePath As String) As BitmapImage
        Dim bi As New BitmapImage
    
        With bi
            .BeginInit()
            .UriSource = New Uri(baseImagePath)
            .DecodePixelWidth = baseWidth / 2 'only seting one DecodePixelXXX property preserves the aspect ratio
            .EndInit()
        End With
    
        Dim enc As New System.Windows.Media.Imaging.JpegBitmapEncoder
        With enc
            .QualityLevel = 50
            .Frames.Add(BitmapFrame.Create(bi))
        End With
    
        Using stream As New IO.FileStream(newImagePath, IO.FileMode.Create)
            enc.Save(stream)
        End Using
    
        Return bi
    End Function
    

    这个代码在我的开发机器上运行正常,但是当我将它安装到服务器上时,服务器会突然停止缓​​存图像,缓存数百个之后。网站的其余部分继续正常运作。我们发现每次尝试创建BitmapImage对象时,页面缓存代码最终会抛出此异常:

    System.ComponentModel.Win32Exception: The system cannot find the file specified
       at MS.Win32.UnsafeNativeMethods.RegisterClassEx(WNDCLASSEX_D wc_d)
       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 MS.Win32.MessageOnlyHwndWrapper..ctor()
       at System.Windows.Threading.Dispatcher..ctor()
       at System.Windows.Threading.Dispatcher.get_CurrentDispatcher()
       at System.Windows.Freezable..ctor()
       at System.Windows.Media.Imaging.BitmapSource..ctor(Boolean useVirtuals)
       at System.Windows.Media.Imaging.BitmapImage..ctor()
       at RemoteFSTester.PageCachingThreadPool.WICResizer.CachePage(String id, Int32 item, Int32 index) in C:\Users\[...]\PageCachingThreadPool.vb:line 127
       at RemoteFSTester.PageCachingThreadPool.CachePage(String id, Int32 item, Int32 index) in C:\Users\[...]\PageCachingThreadPool.vb:line 103
       at RemoteFSTester.PageCachingThreadPool.WorkerMethod(PriorityThreadPoolDelegateArgs args) in C:\Users\[...]\PageCachingThreadPool.vb:line 91
       at MDSA.Util.PriorityThreadpool.PriorityThreadPoolBase.Thread_DoWork(PriorityThreadPoolDelegateArgs args) in C:\Users\[...]\PriorityThreadPoolBase.vb:line 199
    

    即使例外说“找不到指定的文件'”,我也可以直接找到基本图片所在的位置并自行打开文件。

    注意:为了澄清,包含代码和缓存图像的服务器不是容纳基本映像的服务器。代码服务器通过诸如' \ servername \ path \ filename.jpg"之类的URI来获取文件。来自基本图像服务器。

    运行某些测试后,只有在尝试通过BitmapImage对象在IIS服务器上打开图像时才会出现异常。无论是通过UriSource设置文件路径还是创建FileStream对象并将BitmapImage的StreamSource属性设置为它,BitmapImage中都会发生异常。如果文件是通过FileStream对象打开的,它们不会发生,如果通过控制台应用程序打开文件也不会发生。使用BitmapImage对象的控制台应用程序也可以顺利运行。

    所以,最后问我的问题,为什么服务器在通过ASP.NET缓存这些图像时遇到问题,而我的开发机器没有问题?

1 个答案:

答案 0 :(得分:4)

我在这里找到了问题的解决方案: Microsoft Connect Feedback

长话短说,我必须在每个线程进程结束时添加以下代码:

Dim myDispatcher As Dispatcher = Dispatcher.CurrentDispatcher
myDispatcher.BeginInvokeShutdown(DispatcherPriority.Normal)
Dispatcher.Run()