2012-02-23 74 views
0

我的應用程序在BackgroundWorker中加載了大量圖像以保持可用狀態。我的圖像控件綁定到名爲「ImageSource」的屬性。如果這是null,它會在後臺加載並再次提升。在未鎖定文件的情況下在後臺加載圖像

public ImageSource ImageSource 
    { 
     get 
     { 
      if (imageSource != null) 
      { 
       return imageSource; 
      } 

      if (!backgroundImageLoadWorker.IsBusy) 
      { 
       backgroundImageLoadWorker.DoWork += new DoWorkEventHandler(bw_DoWork); 
       backgroundImageLoadWorker.RunWorkerCompleted += 
        new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
       backgroundImageLoadWorker.RunWorkerAsync(); 
      } 

      return imageSource; 
     } 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     bitmap = new BitmapImage(); 
     bitmap.BeginInit(); 
     try 
     { 
       bitmap.CreateOptions = BitmapCreateOptions.DelayCreation; 
       bitmap.DecodePixelWidth = 300; 

       MemoryStream memoryStream = new MemoryStream(); 
       byte[] fileContent = File.ReadAllBytes(imagePath); 
       memoryStream.Write(fileContent, 0, fileContent.Length); 
       memoryStream.Position = 0; 
       bitmap.StreamSource = memoryStream;        

     } 
     finally 
     { 
      bitmap.EndInit(); 
     } 
     bitmap.Freeze(); 
     e.Result = bitmap; 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     BitmapSource bitmap = e.Result as BitmapSource; 

     if (bitmap != null) 
     { 
      Dispatcher.CurrentDispatcher.BeginInvoke(
       (ThreadStart)delegate() 
       { 
        imageSource = bitmap; 
        RaisePropertyChanged("ImageSource"); 
       }, DispatcherPriority.Normal); 
     } 
    } 

這一切都很好,但我的用戶可以更改有問題的圖像。他們選擇在OpenDialog一個新的形象,舊的圖像文件將被替換爲新的ImageSource再次引發與再次相同的文件名加載新的形象:

public string ImagePath 
    { 
     get { return imagePath; } 
     set 
     { 
      imagePath= value; 
      imageSource = null; 
      RaisePropertyChanged("ImageSource"); 
     } 
    } 

在一些系統上的舊文件覆蓋導致異常:

"a generic error occured in GDI+" and "The process cannot access the file..." 

我嘗試了很多東西像BitmapCreateOptions.IgnoreImageCache和BitmapCacheOption.OnLoad加載。這在加載它們時引發異常:

Key cannot be null. 
    Parameter name: key 

如果我在UI線程上沒有BackgroundWorker的情況下嘗試這種方式,它可以正常工作。難道我做錯了什麼?難以在保持文件解鎖的情況下在後臺加載圖像?

+0

請張貼您的「這將導致對ImageSource的新的調用,它再次加載具有相同文件名的新圖像」。你爲什麼再次加載。你爲什麼不使用你的圖像並覆蓋文件? – Paparazzi 2012-02-23 19:12:00

+0

@BalamBalam設置新的(或現有的)文件路徑後,這實際上只是再次調用RaisePropertyChanged(「ImageSource」)。如果我不再次加載ImageSource並且僅複製文件,則更改在UI中不可見並且錯誤仍然存​​在。據我瞭解,複製新文件時會發生錯誤,因爲我的應用程序鎖定了緩存文件。 – Amenti 2012-02-23 19:55:13

+0

爲什麼設置imageSource = null;和RaisePropertyChanged(「ImageSource」); ?你不能只是加載用戶指定的文件到imageSource,RaisePropertyChanged(「ImageSource」)(它將使用imageSource,因爲它不爲空),然後使用後臺線程File.WriteAllBytes? – Paparazzi 2012-02-23 21:04:55

回答

0

那麼,它似乎都是上述的作品。我簡化了這個問題的例子,並在某種程度上丟失了問題。

我可以在我的代碼中看到的唯一區別是,圖像本身的加載被委派給特定的圖像加載器類,它以某種方式創建了問題。當我刪除這個依賴關係時,錯誤消失了。