Home>

I am developing a GUI application using WPF in Visual Studio. I am developing an asynchronous process.
The contents of the process

  • Asynchronous processing starts when button is pressed
  • Check the path corresponding to the list regularly (once per second) and copy it to the work file storage (loop start)
  • Specify the corresponding file copied to Image.Souce (depiction)
  • Processing time is drawn in ViewList
  • Return to loop start

It is a feeling. Only the relevant part is described. This code compiles fine, but I can't see the image in the Image window of my GUI app. On the other hand, similarly, the additional processing to listView described in Invoke as the UI processing part can be depicted well. I'm sorry I've been stuck for a long time, but I would like to ask for your advice. In addition, I thought that File.delete might be bad, so I erased it, but it was useless.

        private async void show_image (object sender, RoutedEventArgs e)
        {
            ShowButton.IsEnabled = false;
            try
            {
                await Task.Run (() =>
                {
                    while (true)
                    {
// ---------- async loop start ------------ /
                    String origin_image_path = "**. Jpg";
                    String dst_image_path = "***. Jpg"
                    File.Copy (origin_image_path, dst_image_path, true);
                    // lock less bitmap
                    MemoryStream data = new MemoryStream (File.ReadAllBytes (dst_image_path));
                    WriteableBitmap wbmp = new WriteableBitmap (BitmapFrame.Create (data));
                    data.Close ();
                    this.Dispatcher.Invoke ((Action) (() =>
                    {
                        listView.Items.Add (new string [] {str_date, "Start"});
                        listView.Items.Add (new string [] {end_date, "End"});
                        this.MainImage.Source = wbmp;
                    }));
                    File.Delete (dst_image_path);
                    System.Threading.Thread.Sleep (1000/60);
// ------------- async loop end --------------- /
                    }
                });
            }
            catch
            {
            }
            finally
            {
                ShowButton.IsEnabled = true;
            }

        }
  • Answer # 1

    The following part

                        this.Dispatcher.Invoke ((Action) (() =>
                        {
                            listView.Items.Add (new string [] {str_date, "Start"});
                            listView.Items.Add (new string [] {end_date, "End"});
                            this.MainImage.Source = wbmp;
                        }));


    I was able to manage it by doing the following.
    The handling of WPF Bitmap is complicated.

                        this.Dispatcher.Invoke ((Action) (() =>{
                            listView.Items.Add (new string [] {str_date, "Start"});
                            listView.Items.Add (new string [] {end_date, "End"});
                            //from here
                            BitmapImage bmp = new BitmapImage ();
                            bmp.BeginInit ();
                            bmp.CacheOption = BitmapCacheOption.OnLoad;
                            bmp.UriSource = new Uri (dst_image_path);
                            bmp.EndInit ();
                            WriteableBitmap wbmp = new WriteableBitmap (bmp);
                            //So far
                            this.MainImage.Source = wbmp;
                        }));

  • Answer # 2

    Let's crush each step by step.

    Does the property of WriteableBitmap have the expected value?

    Is the image displayed if you use synchronous processing instead of asynchronous processing?

    Is it displayed as a single image with no loops?

    If you put MemoryStream ~ File.Delete in Invoke somehow, it seems to work normally.

    As far as I read the annotation of MS's WritableBitmap class, WriteableBitmap is tied to UI thread, so if you want to access it asynchronously, it is correct to create WriteableBitmap on the UI thread side beforehand and lock it on the Task side to write. Seems like a procedure.
    WriteableBitmap class

    There seems to be a hand not to use WriteableBitmap itself.
    WritePixels of WriteableBitmap in a Task-Stack Overflow