2010-03-18 5 views
1

WPF BackgroundWorker를 사용하여 축소판을 만듭니다. 내 작업자 기능과 같이 보인다 :다른 스레드의 BitmapFrame

기능이 시작됩니다 "완료"를 BackgroundWorker에, 내가 VS2008의 출력 창에서 볼 수 있습니다 전에이 함수는 예외가 생성됩니다, 완료하고
private void work(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
    var paths = e.Argument as string[]; 
    var boxList = new List<BoxItem>(); 
    foreach (string path in paths) 
    {     
     if (!string.IsNullOrEmpty(path)) 
     { 
     FileInfo info = new FileInfo(path); 
     if (info.Exists && info.Length > 0) 
     { 
      BitmapImage bi = new BitmapImage(); 
      bi.BeginInit(); 
      bi.DecodePixelWidth = 200; 
      bi.CacheOption = BitmapCacheOption.OnLoad; 
      bi.UriSource = new Uri(info.FullName); 
      bi.EndInit(); 
      var item = new BoxItem(); 
      item.FilePath = path; 
      MemoryStream ms = new MemoryStream(); 
      PngBitmapEncoder encoder = new PngBitmapEncoder(); 
      encoder.Frames.Add(BitmapFrame.Create(bi)); 
      encoder.Save(ms); 
      item.ThumbNail = ms.ToArray(); 
      ms.Close(); 
      boxList.Add(item); 
     } 
     } 
    } 
    e.Result = boxList; 
    } 
    catch (Exception ex) 
    { 
    //nerver comes here 
    } 
} 

. 예외의 수는 생성

A first chance exception of type 'System.NotSupportedException' occurred in PresentationCore.dll 

축소판의 수를 생성 할 같다 : 것 같습니다. "시행 착오"나는에 문제를 격리 한 방법을 사용

: BitmapFrame.Create (BI)

그 라인을 제거는 (내 기능 쓸모하게)도 예외를 제거합니다.

나는 이것에 대한 설명을 찾지 못했거나 백그라운드 스레드에서 축소판을 만드는 더 좋은 방법을 찾지 못했습니다.

답변

1

Lasse, 내가 UI 스레드 내에서해야 할 UI 스레드 외부에서 작업을 수행하기 때문에 문제가 발생한다고 생각합니다. UI 요소 (BitmapImage, BitmapFrame)를 만들고 UI 컨테이너에 추가하는 것은 UI 스레드에서 수행해야합니다. (만약 내가 틀렸다면 누군가는 나를 바로 잡습니다.)

과도한 기간 동안 응용 프로그램을 차단하지 않고도 UI 스레드에서 이러한 요소를 만들 수있는 몇 가지 방법이 있습니다. 가장 쉬운 방법은 BackgroundWorker의 ProgressChanged 이벤트를 사용하는 것입니다. ProgressChanged는 UI 스레드에서 호출되므로이 상황에 완벽합니다.

작업자의 ProgressChanged 이벤트를 사용하여 UserState 인수에 축소판을로드하는 데 필요한 경로를 전달할 수 있습니다.

+0

그런 식으로 말하면, 당신은 요점이 있다고 생각합니다. ProgressChanged 이벤트를 사용하여 ,,, 어떻게 작업자 스레드로 값을 다시 보냅니 까 ??? –

0

입력 해 주셔서 감사합니다. 다른 솔루션을 찾기 시작했고이 문제를 생각해냅니다.

 try 
     { 
      var paths = e.Argument as string[]; 
      var boxList = new List<BoxItem>(); 

      foreach (string path in paths) 
      { 
       using (Image photoImg = Image.FromFile(path)) 
       { 
        int newWidth = 200; 
        int width = newWidth; 
        int height = (photoImg.Height * newWidth)/photoImg.Width; 

        var thumbnail = new Bitmap(width, height); 

        using (Graphics g = Graphics.FromImage((System.Drawing.Image)thumbnail)) 
        { 
         g.DrawImage(photoImg, 0, 0, width, height); 
         using (var ms = new System.IO.MemoryStream()) 
         { 
          var item = new BoxItem(); 
          item.FilePath = path; 

          thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 

          item.ThumbNail = ms.ToArray(); 
          boxList.Add(item); 
         } 
        } 
       } 
      } 
      e.Result = boxList; 
     } 

     catch (Exception exp) 
     { 
     } 

UI 요소를 사용하지 않고 있습니다. 멋지게 작동합니다. 감사합니다. . // lasse

+0

만세! 미안하지만 질문에 일찍 답장을 보지 못했지만 모든 것을 다 정리 한 것처럼 보입니다. 굉장해. –

관련 문제