2009-07-20 14 views
3

Ich versuche, einen Fortschrittsbalken zu erstellen, der asynchron zum Hauptprozess arbeiten wird. Ich bin ein neues Ereignis erstellt und aufgerufen es aber jedes Mal wenn ich dann versuchen, Operationen auf dem Fortschrittsbalken auszuführen ich folgende Fehlermeldung empfangen:WPF: Asynchrone Fortschrittsbalken

„Der aufrufende Thread dieses Objekt nicht zugreifen, da ein anderer Thread besitzt es“

Der folgende Code versucht, eine Instanz des Fortschrittsbalkens als Objekt an das Ereignis zu senden. Sie ist offensichtlich fehlgeschlagen, vermittelt Ihnen jedoch eine Vorstellung davon, wie der Code aussieht.

private event EventHandler importing; 

    void MdbDataImport_importing(object sender, EventArgs e) 
    { 
     ProgressBar pb = (ProgressBar)sender; 
     while (true) 
     { 
      if (pb.Value >= 200) 
       pb.Value = 0; 

      pb.Value += 10; 
     } 
    } 

    private void btnImport_Click(object sender, RoutedEventArgs e) 
    { 
     importing += new EventHandler(MdbDataImport_importing); 
     IAsyncResult aResult = null; 

     aResult = importing.BeginInvoke(pbDataImport, null, null, null); 

     importing.EndInvoke(aResult); 
    } 

Hat jemand Ideen, wie man das macht.

Vielen Dank im Voraus SumGuy.

Antwort

5

Sie sollten so etwas wie dieses

pb.Dispatcher.Invoke(
        System.Windows.Threading.DispatcherPriority.Normal, 
        new Action(
        delegate() 
        { 

         if (pb.Value >= 200) 
          pb.Value = 0; 

         pb.Value += 10; 
        } 
       )); 

in Ihrer while-Schleife verwenden

+0

Dies gilt dank der Arbeit aber es ziemlich langsam ist. Nicht sicher, ob es so ist, wie ich es gemacht habe, ich muss etwas mehr herumstochern. – SumGuy

+4

1) Anstatt Invoke aufzurufen, beginne BeginInvoke (du würdest nicht wollen, dass dein Hintergrundverarbeitungsthread wartet, bis GUI neu gezeichnet wird, würdest du?) ?) 2) Versuchen Sie nicht, den Fortschritt jede Mikrosekunde zu aktualisieren, wählen Sie ein vernünftiges Intervall. –

0

Sie müssen pbDataImport an den Dispatcher delegieren. Nur so kann die GUI-Dispatcher Änderungen an GUI steuert :)

0

ich hinein geschaut haben weiter und das asynchrone Verfahren wird funktionieren sowie die folgende Methode von MSDN.

In XAML:

<ProgressBar Width="100" Height="20" Name="progressBar1"> 
    <ProgressBar.Triggers> 
     <EventTrigger RoutedEvent="ProgressBar.Loaded"> 
      <BeginStoryboard> 
       <Storyboard> 
        <DoubleAnimation Storyboard.TargetName="progressBar1" From="0" To="100" Duration="0:0:5" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </ProgressBar.Triggers> 
</ProgressBar> 

In C#:

 ProgressBar progbar = new ProgressBar(); 
     progbar.IsIndeterminate = false; 
     progbar.Orientation = Orientation.Horizontal; 
     progbar.Width = 150; 
     progbar.Height = 15; 
     Duration duration = new Duration(TimeSpan.FromSeconds(10)); 
     DoubleAnimation doubleanimation = new DoubleAnimation(100.0, duration); 
     progbar.BeginAnimation(ProgressBar.ValueProperty, doubleanimation); 

Mein Problem war, dass ich eine gespeicherte Prozedur ausführen, als ich die Fortschrittsbalken wollte auszuführen und dies hält den Prozess und deshalb macht den Fortschrittsbalken ein wenig Müll, auch wenn asynchron.

Ich nehme an, die andere Möglichkeit wäre, die gespeicherten Prozeduren asynchron zu machen, was denkst du?

Cheers, SumGuy

Edit (17. Mai 2010)

Es scheint, sind viele Leute in diesem Beitrag nicht interessiert, so dachte ich, ich würde diese hinzufügen. Ich fand ein ausgezeichnetes Stück, das zusammen mit einem leckeren Stück auf Fortschrittsbalken im Detail in WPF Asynchronous Arbeit beschreibt:

http://www.codeproject.com/KB/WPF/AsynchronousWPF.aspx

+0

Wissen Sie, wann SP beendet wird? Warum benutzt du nicht unbestimmten Fortschrittsbalken? http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar.isindeterminate.aspx –