Ski
Ski

Reputation: 1182

ASP.NET Throws Win32Exception when creating BitmapImage, cannot find file specified

I have been developing a book viewing website that takes rather large images (upwards of 77+ megapixels) and scales them down before serving the image. It basically does the following algorithm:

  1. If the requested book has already been cached, serve the cached images.
  2. If the book hasn't been cached, add the book to our book-caching thread pool.
  3. The book-caching thread pool adds each book's page to our page-caching thread pool.
  4. The page-caching thread pool caches the image (located on a server on our LAN) by halving the image over and over until we have cached versions of the image reduced by 2x,4x,8x,16x,32x, and 64x.

Here is the code that halves an individual image. Note the use of 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

This code was working fine on my dev machine, but when I installed it onto a server that server would suddenly stop caching images, after caching hundreds. The rest of the website continued to work fine. We found that the page caching code would eventually throw this exception every time it tried to create the BitmapImage object:

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

Even though the exception says 'cannot find the file specified', I can go straight to where the base image is located and open the file myself.

NOTE: Just to clarify, the server that houses the code and cached images is not the server that houses the base images. The code server grabs the file via a URI like '\servername\path\filename.jpg" from the base-image server.

After running some tests, the exceptions only occur when trying to open images on our IIS server via the BitmapImage object. The exception in BitmapImage happens whether I set the file path via UriSource or make a FileStream object and set the BitmapImage's StreamSource property to it. They don't occur if the files are opened via a FileStream object, nor do they occur if the files are opened via a console application. A console application using the BitmapImage object also runs without problem.

So, to finally ask my question, why does the server have trouble caching these images via ASP.NET while my dev machine has no problem?

Upvotes: 4

Views: 2796

Answers (1)

Ski
Ski

Reputation: 1182

I found the solution to the problem here: Microsoft Connect Feedback

Long story short, I had to add the following code where it would run at the end of every thread process:

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

Upvotes: 4

Related Questions