2016-03-26 5 views
0

Was ist falsch in meinem Programm? Ich kann einen ausführenden Thread nicht von der Benutzeroberfläche trennen. Die Benutzeroberfläche kann während der Ausführung des Threads nicht erreicht werden.Separate Thread von UI

Das ist mein Viewmodel:

Erste Option:

// on button click: 
this.CreateImageList(); 

private void CreateImageList() 
{ 
    this.images.Clear(); 

    ThreadStart threadStart = delegate 
    { 
     this.dispatcher.BeginInvoke(new ThreadStart(delegate 
     { 
      foreach (var filePath in this.fileBuffer) 
      { 
       var result = new ImageObject(filePath); 
       if (result.Image != null) 
       { 
        this.images.Add(result); 
        this.dispatcher.Invoke(() => this.StatusText = filePath, DispatcherPriority.Render); 
       } 
      } 

      this.RaisePropertyChanged("Images"); 
     })); 
    }; 

    var thread = new Thread(threadStart); 
    thread.IsBackground = true; 
    thread.Start(); 
} 

Zweite Option:

// on button click: 
this.CreateImageList(); 

private async void CreateImageList() 
{ 
    await this.CreateImageListAsync(); 
} 

private async Task CreateImageListAsync() 
{ 
    this.images.Clear(); 
    var countTotal = this.fileBuffer.Count(); 
    var index = 0; 

    await Task.Run(() => this.dispatcher.Invoke(
    (() => 
    { 
     foreach (var filePath in this.fileBuffer) 
     { 
      var result = new ImageObject(filePath); 
      if (result.Image != null) 
      { 
       this.images.Add(result); 

       var percent = (index * 100)/countTotal; 
       this.DoForce(() => this.StatusText = percent + "% " + filePath); 
      } 

      index++; 
     } 

     this.RaisePropertyChanged("Images"); 
    }), DispatcherPriority.SystemIdle)); 
} 

public void DoForce(Action action) 
{ 
    this.dispatcher.Invoke(DispatcherPriority.Render, action); 
} 

In ersten und in der zweiten Option das Programm funktionieren. Aber in der ersten und in der zweiten Option kann die Benutzeroberfläche nicht für den Benutzer erreicht werden

+0

Was sind die Fehler, die Sie bekommen oder wie kann das "nicht erreichbar" angezeigt werden? Bitte stellen Sie eine genaue Fehlerbeobachtung zur Verfügung, nicht irgendeine Interpretation dessen, was Sie gesehen haben! –

+3

Dies liegt daran, dass Sie den Delegat auf den UI-Dispatcher selbst setzen, der ihn jedoch auf den UI-Thread zurücksetzt. Sie sollten nur UI-Aufgaben an UI-Dispatcher delegieren, Rest kann im Hintergrundthread ausgeführt werden. –

+0

Keine Fehler! Das Programm läuft gut! Aber ich kann das Fenster nicht bewegen oder auf irgendeinen Knopf klicken usw. – peter70

Antwort

4

Dies liegt daran, Sie delegieren setzen auf UI-Dispatcher, die ohnehin auf UI-Thread ausgeführt wird (was nicht reagierende UI).

Sie sollten delegieren nur UI Aufgaben auf UI Dispatcher, Rest kann auf Hintergrund Thread ausgeführt werden.

+3

Ja, das ist es. Vielen Dank! – peter70

0

Ich habe den Eindruck, dass separate Threads, ob ein Hintergrund oder UI-Thread, keinen Zugriff auf den Haupt-Thread haben (außer ProgressChanged). Ich habe viel Zeit mit diesem Problem verbracht und konnte keinen Weg finden, dauerhaft auf den Haupt-Thread eines sekundären Threads zuzugreifen.

Meine Lösung für den UI-Thread war die Verwendung von WndProc zum Chatten zwischen Threads im Zusammenspiel mit erweiterten Werten (lParam) und/oder Registrierungswerten.

Mit dem Hintergrund-Worker-Thread habe ich über einen Fenstereigenschaftszeiger auf den Hauptthread auf den Hauptthread im Fortschrittsereignis zugegriffen. Sie können auf den Hauptthread nur über das ProgressChanged-Ereignis im BgWorker zugreifen.