Scott Mitchell
Scott Mitchell

Reputation: 8759

How do I determine when Dispatcher.BeginInvoke completes?

I have a Silverlight 5 application that uses ImageTools for Silverlight to save a Canvas to a PNG image. I understand that I need to work with the Canvas on the UI thread and have the following code, which works:

if (saveFileDialog.ShowDialog() == true)
{
    var stream = saveFileDialog.OpenFile();

    writeableBitmap.Dispatcher.BeginInvoke(delegate
    {
        ExtendedImage extendedImage = writeableBitmap.ToImage();

        new PngEncoder().Encode(extendedImage, stream);
    });
}

The problem is that if the Canvas is very large it can take a noticeable time for the code in the BeginInvoke to complete. Since this is running on the UI thread it freezes the browser window during its execution.

After the user selects the location of where to save the exported image, I'd like to popup some child window that tells the user, "Please wait...", then run the image saving code posted above, and afterwards hide the child window automatically, but I'm not having much luck accomplishing that.

For starters, the BeginInvoke code runs asynchronously, so how do I know when it has completed?

Upvotes: 0

Views: 128

Answers (1)

Silver Solver
Silver Solver

Reputation: 2320

If you need to call ToImage() on the UI Thread thats fine, but it doesnt mean you have to encode the image too.

Something like this will ensure the UI stays responsive.

if (saveFileDialog.ShowDialog() == true)
{
    using (var stream = saveFileDialog.OpenFile())
    {
        writeableBitmap.Dispatcher.BeginInvoke(delegate
        {
            ExtendedImage extendedImage = writeableBitmap.ToImage();
            System.Threading.ThreadPool.QueueUserWorkItem(item =>
            {
                new PngEncoder().Encode(extendedImage, stream);
            });
        });
    }
}

Upvotes: 1

Related Questions