Search code examples
c#wpfdrawingexecutionshapes

Executing Image download before intended script


I ran into this "interesting" issue today. I have a button on a wpf window and when I press it, I want a rectangle to become visible and expand to the size of my main window. Then the text held inside the rectangle to align at it's centre. After this happens, I want the script to download an image from the web to start executing. However... When I press the button, my rectangle does not become visible, and instead the exe starts downloading the image... I thought the code should be executed in order...

On button_1 press(blah blah){

expander1.IsExpanded = false; //just an expander i use to hide a few elements

            pleasewait.Visibility = Visibility.Visible; //pleasewait - rectangle
            plswait_label.Visibility = Visibility.Visible; // plswait_lable - label
            pleasewait.Height = window_main.Height;
            pleasewait.Width = window_main.Width;
            plswait_label.HorizontalAlignment = HorizontalAlignment.Center;
            plswait_label.VerticalAlignment = VerticalAlignment.Center;

            image1.Source = null; // dumping previous image before downloading a new one



//This is the script to download the image and do some other stuff..
    string path = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);

    Uri urlUri = new Uri(address.Text);
    var request = WebRequest.CreateDefault(urlUri);

    byte[] buffer = new byte[4096];

    using (var target = new FileStream(path + @"\Temp\br_temp.png", FileMode.Create, FileAccess.Write))
    {
        using (var response = request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {
                int read;

                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    target.Write(buffer, 0, read);
                }
            }
        }
    }


    Bitmap resizedImage;
    System.Drawing.Size newSize = new System.Drawing.Size(266, 150);

    using (System.Drawing.Image originalImage = System.Drawing.Image.FromFile(path + @"\Temp\br_temp.png"))
        resizedImage = new System.Drawing.Bitmap(originalImage, newSize);
    resizedImage.Save(path + @"\Temp\temp.png", System.Drawing.Imaging.ImageFormat.Jpeg);
    resizedImage.Dispose();

    BitmapImage MainImage = new BitmapImage();
    MainImage.BeginInit();
    MainImage.UriSource = new Uri(path + @"\Temp\temp.png");
    MainImage.DecodePixelWidth = 266;
    MainImage.DecodePixelHeight = 150;
    MainImage.EndInit();
    image1.Source = MainImage;
}

Funny enough, if I remove the downloading code, the rectangle actually does what I want it to..


Solution

  • The download is blocking the UI thread. Nothing on the UI will work until the download is complete.

    You need to move the download code off the UI thread.

    An easy way to do this is with a BackgroundWorker

    As always, I recommend reading Joe Albahari's ebook