2016-04-13 4 views
2

У меня есть метод, который открывает изображение из zip-файла и возвращает это изображение как BitmapImage.BitmapImage: Как дождаться инициализации BitmapImage перед возвратом изображения? (C# .NET)

public BitmapImage GetImageFromSource() 
{ 
    using (System.IO.Compression.ZipArchive zi = System.IO.Compression.ZipFile.Open(ZipFileLocation, System.IO.Compression.ZipArchiveMode.Read)) 
    { 
     using (Stream source = zi.GetEntry(InternalLocation).Open()) 
     { 
      BitmapImage img = new BitmapImage(); 
      img.BeginInit(); 
      img.CacheOption = BitmapCacheOption.OnLoad; 
      img.StreamSource = source; 
      img.EndInit(); 

      //sleeping here allows img to complete initialization 
      //not sleeping here means img is still blank upon return 
      System.Threading.Thread.Sleep(100); 

      return img; 
     } 
    } 
} 

Почтовый файл содержит смесь больших и малых изображений. Если изображение велико, img может не завершиться инициализацией до того, как программа вернется к возврату. Если это произойдет, метод возвращает пустой битмап.

Если я сплю до возвращения, метод работает, и с достаточной задержкой большие изображения успешно инициализируются.

Сон не идеален, так как он замедляет программу путем ненужной блокировки основной нити. Как я могу заставить метод ждать завершения инициализации перед возвратом BitmapImage?

Я попытался загрузить IsDownload и событие DownloadCompleted. Для IsDownload всегда установлено значение «true», и DownloadCompleted никогда не запускается.

+0

ли [ 'DownloadCompleted'] (https://msdn.microsoft.com/en-us /library/system.windows.media.imaging.bitmapsource.downloadcompleted(v=vs.110).aspx) Возможно, произошел пожар? – DavidG

+0

Странно - только иногда. Он срабатывает, но только когда img уже предоставлено время для завершения инициализации (например, с помощью Sleep). –

ответ

2

На самом деле не очень хорошая практика блокировать основной поток, ожидающий загрузки растрового изображения, для чего может потребоваться отгрузка нагрузки по какой-либо причине. Это на самом деле то, что происходит здесь, и когда нагрузка действительно происходит, вы уже удалили переменные файла. Вы можете вернуть изображение сразу, но вы должны отложить утилизацию этих переменных до тех пор, после загрузки файла:

public BitmapImage GetImageFromSource() 
{ 
    System.IO.Compression.ZipArchive zi = System.IO.Compression.ZipFile.Open(ZipFileLocation, System.IO.Compression.ZipArchiveMode.Read); 
    Stream source = zi.GetEntry(InternalLocation).Open(); 

    BitmapImage img = new BitmapImage(); 
    img.DownloadCompleted += (s, e) => 
    { 
     source.Dispose(); 
     zi.Dispose(); 
    }; 

    img.BeginInit(); 
    img.CacheOption = BitmapCacheOption.OnLoad; 
    img.StreamSource = source; 
    img.EndInit(); 

    return img; 
} 
Смежные вопросы