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

标签 asp.net iis bitmapimage

我一直在开发一个图书浏览网站,它拍摄相当大的图像(大于 77 兆像素)并在提供图像之前将它们缩小。它基本上执行以下算法:

  • 如果请求的图书已被缓存,则提供缓存的图像。
  • 如果书没有被缓存,将书添加到我们的书缓存线程池中。
  • 书籍缓存线程池将每本书的页面添加到我们的页面缓存线程池中。
  • 页面缓存线程池通过反复将图像减半来缓存图像(位于我们 LAN 上的服务器上),直到我们将图像的缓存版本缩小 2x、4x、8x、16x、32x 和 64x。

  • 这是将单个图像减半的代码。注意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 缓存这些图像有问题?

    最佳答案

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

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

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

    关于ASP.NET 在创建 BitmapImage 时抛出 Win32Exception,找不到指定的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8995588/

    相关文章:

    c# - 迁移到服务器后 SignalR 不工作

    java.lang.OutOfMemoryError : bitmap size exceeds VM budget & java. io.FileNotFoundException

    android - 为什么 setImageBitmap 对自定义 ImageButton 没有影响?

    android - 在 Android 中使用 BitmapFactory.decodeStream() 从缓存中加载图像

    javascript - asp LinkBut​​ton __doPostBack

    asp.net - 从任何请求输入绑定(bind) : FromQuery, FromRoute, FromForm

    c# - 在 ASP.NET 中以编程方式设置用户控件的文化

    docker - Docker中的IIS返回403

    c# - Membership.GetUser 结果导致对象引用未设置为对象的实例

    asp.net - 从自定义 404 页面获取 Referer