2014-10-22 1 views
0

시간이 많이 소요되는 메서드가있어서 BackgroundWorker를 구현하려고했지만 UI 컨트롤에 액세스 할 수 없습니다.이 UI 컨트롤을 읽고 해봤지만 아무 소용이 없습니다. 내 방법은 무엇UI 컨트롤에 액세스하는 데 시간이 많이 걸리는 작업을 수행하면서 UI를 차단하지 않는 방법은 무엇입니까?

: 새 BitmapImage를 작성은 로컬 또는 (매개 변수)를 스트리밍 소스를 설정 ConvertToGrayscale에 사용되는 새로운 WriteableBitmap,에 기록하고 폴더에 IsolatedStorage에 BW 복사를 저장합니다.

이렇게 모든 것이 매우 빠르게 발생합니다. 하지만, 25 개 미만의 소스 이미지를 말한 경우에만. 제가 100 개 이상의 Images를 가지고 있다면 이것은 20 초 이상으로 꽤 오래 걸립니다. 그러므로 동일한 PhoneApplicationPage에 ProgressBar를 보여주고 싶습니다. 그러나 UI를 차단하지 않고 ProgressBar를 표시하는 방법에 어려움을 겪고 있습니다. 그 일을하고있다.

void GetImages() 
    { 

     if (!myIsolatedStorage.DirectoryExists("ImagesBW") && !_appsettings.Contains("_update")) 
     { 

      myIsolatedStorage.CreateDirectory("ImagesBW "); 
      for (int i = 0; i < coll.Desserts.Count; i++) 
      { 
       BitmapImage bmp = new BitmapImage(); 
       bmp.CreateOptions = BitmapCreateOptions.None; 

       if (coll.Desserts[i].HasAssociatedImage) 
       { 
        bmp.SetSource(coll.Desserts[i].GetImage()); 
        WriteableBitmap wb = new WriteableBitmap(bmp); 
        ConvertToGrayscale(wb); 
        BitmapImage bit = ConvertWBtoBI(wb); 
        SaveBWCopy(bi, i.ToString()); 
       } 
       else 
       { 
        bmp.UriSource = new Uri("/Assets/Images/MissingArt.png", UriKind.Relative); 
        WriteableBitmap wb = new WriteableBitmap(bmp); 
        ConvertToGrayscale(wb); 
        BitmapImage bit = ConvertWBtoBI(wb); 
        SaveBWCopy(bi, i.ToString()); 
       } 

      } 

      _appsettings["_firstLaunch"] = "false"; 
      _appsettings.Save(); 

     } 

     else if (myIsolatedStorage.DirectoryExists("ImagesBW ") && _appsettings.Contains("_update")) 
     { 
      string[] files = myIsolatedStorage.GetFileNames("ImagesBW/*"); 

      for (int s = 0; s < files.Length; s++) 
      { 
       myIsolatedStorage.DeleteFile("ImagesBW/" + s + ".jpg"); 
      } 

      myIsolatedStorage.DeleteDirectory("ImagesBW"); 
      myIsolatedStorage.CreateDirectory("ImagesBW"); 

          for (int i = 0; i < coll.Desserts.Count; i++) 
      { 
       BitmapImage bmp = new BitmapImage(); 
       bmp.CreateOptions = BitmapCreateOptions.None; 

       if (coll.Desserts[i].HasAssociatedImage) 
       { 
        bmp.SetSource(coll.Desserts[i].GetImage()); 
        WriteableBitmap wb = new WriteableBitmap(bmp); 
        ConvertToGrayscale(wb); 
        BitmapImage bit = ConvertWBtoBI(wb); 
        SaveBWCopy(bi, i.ToString()); 
       } 
       else 
       { 
        bmp.UriSource = new Uri("/Assets/Images/MissingArt.png", UriKind.Relative); 
        WriteableBitmap wb = new WriteableBitmap(bmp); 
        ConvertToGrayscale(wb); 
        BitmapImage bit = ConvertWBtoBI(wb); 
        SaveBWCopy(bi, i.ToString()); 
       } 

      } 

      _appsettings.Remove("_update"); 
      _appsettings.Save(); 

     } 

     btnStart.IsEnabled = true; 
    } 
+0

이 있어야한다'Invoke' 방법을 업데이트하려면이 옵션을 추가 할 수 있습니다. wpf에서 그것은'Dispatcher.Invoke'입니다. UI에 액세스해야 할 때'Task' 또는'Thread' (또는'BackgroundWorker')로 실행되는 백그라운드 처리를 주기적으로 차단해야합니다. 가장 좋은 경우는 한 번에 (시작 및/또는 끝에서) 모든 것을 얻을 수 있고, 호출 할 필요없이 간단하게 작업 할 수있는 경우입니다 (필요한 경우 정기적 인 상태 보고서 사용). – Sinatr

+0

안녕하세요. 너무 늦어서 미안하지만 내 시나리오를 더 자세히 설명해 주시겠습니까? 더 잘 이해할 수 있습니까? –

답변

-1

Backgroundorker이 가장 ​​좋은 건입니다 :

는 내가 가지고있는 코드입니다. 웹상에 엄청난 양의 리소스가 있습니다. 그러나 Backgroundworker는 UI와는 별도의 스레드에서 실행됩니다. 대리 스레드 또는 UI 스레드에 대한 액세스를 제공하는 Backgroundworker의 ProgressChanged 메서드를 통해 주 스레드 UI에 액세스 할 수 있습니다.

당신은 이것을 가지고 있다고합니다.

public MainWindow() 
    { 
     InitializeComponent(); 

     //if you want to disable you button you can do it here 

     BackgroundWorker _bw = new BackgroundWorker(); 
     _bw.DoWork += new DoWorkEventHandler(_bw_DoWork); 
     _bw.WorkerReportsProgress = true; 
     _bw.ProgressChanged += new ProgressChangedEventHandler(_bw_ProgressChanged); 
     _bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bw_RunWorkerCompleted); 
     _bw.RunWorkerAsync(); 

     //or here 
     //Display progress bar here too 

    } 

    void _bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     //this can give you access to the UI after work is completed 
     // to check that everything is ok or hide progress bar 
    } 

    void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     //this will give you access to the UI in the middle of you work like update progress bar 
    } 

    void _bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //actual work here including GetImages 
     //work work work 
     GetImages(); 

    } 

SaveBWCopy 한 후 getimages 방법에서 당신은 어딘가에 진행 표시 줄을

 _bw.ReportProgress(int progress) 
     //progress is the percentage you want to send to progress bar to display that is going to be in the e eventargument you passed. 
+0

하지만 내 Mehod에서 볼 수 있듯이 UI 컨트롤 (BitmapImage, WriteableBitmap)에 주로 액세스합니다. 그렇다면 어떻게하면 내 방법을 BackgroundWorker에 통합 할 것을 제안합니까? –

+0

다른 BI 컨트롤과 WB 및 btnStart에 액세스하는 다른 UI 컨트롤은 무엇입니까? – KonB

+0

하지만 그 중 가장 많이 사용되는 것들 = 인스턴스 초기화, 그레이 스케일로 변환, 다시 BitmapImage로 변환하는 것. 이것은 가장 많은 시간을 차지하는 부분입니다. –