Yustme
Yustme

Reputation: 6265

disposing generic list of bitmapimages

How can i dispose all the images in a generic list in WPF?

Here is my try:

//piclist is a global variable pointing to a folder on harddrive 
foreach (string s in this.piclist)  
{
   this.picsToDisplay.Add(this.BitmapFromUri(new Uri(s)));
}

private BitmapImage LoadImage(string myImageFile)
    {
        BitmapImage myRetVal = null;
        if (myImageFile != null)
        {
            BitmapImage image = new BitmapImage();
            using (FileStream stream = File.OpenRead(myImageFile))
            {
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.StreamSource = stream;
                image.EndInit();
            }
            myRetVal = image;
        }
        return myRetVal;
    }

and this is how i clear and dispose everything:

if (this.picsToDisplay.Count > 0)
        {
            foreach (BitmapImage b in this.picsToDisplay)
                b.StreamSource.Dispose();

            this.picsToDisplay.Clear();
        }

        Array.ForEach(Directory.GetFiles(this.tempPics),
                        delegate(string path) { File.Delete(path); });

It crashes first at b.StreamSource.Dispose(); Saying that streamsource is null 'reference not set to an instance of an object'

If i comment out that line, it crashes at this part: File.Delete(path); With the message that the picture i'm trying to delete is in use.

The pictures getting displayed in an image control in WPF. Its source is already set to NULL before i proceed to dispose etc.

What am i missing guys?

============ EDIT

private void btnLoadPictures_Click(object sender, EventArgs e)
{
    this.ClearPicturesFromList();
    DirectoryInfo Dir = new DirectoryInfo(this.pictures);
    List<string> stringList = new List<string>();
    FileInfo[] picList = Dir.GetFiles();

    stringList = (from FI in picList
         where FI.LastWriteTime.Date.ToString("dd-MM-yyyy") == 
         this.dpPictureDate.SelectedDate.Value.ToString("dd-MM-yyyy")
         select (FI.FullName)).ToList();

try
{
if (Directory.Exists(this.tempPics))
{
    if (stringList.Count > 0)
    {
        foreach (string s in stringList)
        {
            string destFolder = System.IO.Path.Combine(this.tempPics, System.IO.Path.GetFileName(s));
            File.Copy(s, destFolder, true);
        }

        DirectoryInfo Dir2 = new DirectoryInfo(this.tempPics);
        FileInfo[] pics = Dir2.GetFiles();

        this.picsInTempFolder = (from FI in pics
                            select (FI.FullName)).ToList();

        foreach (string s in this.picsInTempFolder)
        {
            this.picsToDisplay.Add(this.LoadImage(s));
        }

        this.indexCounter = 0;
        this.imgBox.Source = (BitmapImage)this.picsToDisplay[this.indexCounter];
        this.tbxPictureName.Text = System.IO.Path.GetFileName(this.picsInTempFolder[this.indexCounter]);
        stringList.Clear();
        pics = null;
        }
    }
}

catch (Exception exp)
{
    this.WriteToRichTextBox(exp.ToString());
}

}

pressing the clearimages button for the first time, i get the exception about the file being in use. doing it the second time, actually works fine.

putting a thread.sleep between clearing all lists and stuff than delete the files in the temp directory doenst work. but somehow it needs a sort of delay.

Upvotes: 2

Views: 941

Answers (1)

Haris Hasan
Haris Hasan

Reputation: 30097

try this method for loading images

 private BitmapImage LoadImage(string myImageFile)
        {
            BitmapImage myRetVal = null;
            if (myImageFile != null)
            {
                BitmapImage image = new BitmapImage();
                using (FileStream stream = File.OpenRead(myImageFile))
                {
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = stream;
                    image.EndInit();
                }
                myRetVal = image;
            }
            return myRetVal;
        }

Upvotes: 1

Related Questions