2009-07-20 7 views
3

J'essaie de créer une barre de progression qui fonctionnera de manière asynchrone avec le processus principal. Je suis créé un nouvel événement et a invoqué mais chaque fois que je puis essayer d'effectuer des opérations sur la barre de progression, je reçois l'erreur suivante:WPF: Barre de progression asynchrone

« Le thread appelant ne peut pas accéder à cet objet parce qu'un autre thread est le propriétaire »

Le code suivant est une tentative d'envoi d'une instance de la barre de progression à l'événement en tant qu'objet, il a manifestement échoué mais cela vous donne une idée de l'apparence du code.

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); 
    } 

Quelqu'un a-t-il des idées sur la façon de procéder? Merci d'avance SumGuy.

Répondre

5

Vous devez utiliser quelque chose comme ça

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

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

         pb.Value += 10; 
        } 
       )); 

dans votre boucle while

+0

Cela fait grâce au travail mais il est assez lent. – SumGuy

+4

1) Au lieu de Invoke, utilisez BeginInvoke (vous ne voulez pas que votre thread de traitement en arrière-plan attende que l'interface graphique soit redessinée, voulez-vous ?) 2) N'essayez pas de mettre à jour la progression toutes les microsecondes, choisissez un intervalle sensible. –

0

Vous devez déléguer pbDataImport au répartiteur. Seul le GUI-répartiteur peut apporter des modifications aux commandes GUI :)

0

je l'ai regardé dans davantage et la méthode asynchrone sera fonctionne ainsi que la méthode suivante à partir de MSDN.

En 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> 

En 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); 

Mon problème est que je remplissais une procédure stockée quand je voulais la barre de progression pour réaliser et cela est le processus et donc rend la barre de progression un peu nulle, même lorsqu'elle est asynchrone.

Je suppose que l'autre possibilité serait de rendre les actions de procédure stockées asynchrones, qu'en pensez-vous?

Cheers, SumGuy

Modifier (17 mai 2010)

Il semble que beaucoup de gens sont intéressés par ce poste, donc je pensais que j'ajouter ceci. J'ai trouvé un excellent morceau qui décrit le travail Asynchronous dans WPF en détail avec un peu savoureux sur les barres de progression:

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

+0

savez-vous quand SP va finir? Pourquoi n'utilisez-vous pas une barre de progression indéterminée? http://msdn.microsoft.com/en-us/library/system.windows.controls.progressbar.isindeterminate.aspx –

Questions connexes