WPF C # - Mettre à jour la barre de progression d'un autre thread
Je suis coincé à essayer de mettre à jour une barre de progression à partir d'autres threads couru dans une classe différente. Pour expliquer ce que je fais, je pense, une image sera meilleure. Je veux mettre à jour la barre de progression dans l' //ICI point :
J'ai essayé à l'aide d'un délégué, essayé avec ReportProgress et je pense que je l'ai fait essayé à utiliser tout ce que google a signalé dans les 100 premiers résultats, sans succès. Je suis encore à apprendre WPF et peut-être idiot comme façon de procéder, je suis à la recherche d'une façon rapide et sale pour faire le travail, mais n'hésitez pas à me dire ce que je doit refonte pour un nettoyeur application.
MODIFIER : Plus de code.
Dans ExecutorWindow.xaml.cs :
public void RunExecutor()
{
//CREATE BACKGROUNDWORKER FOR EXECUTOR
execBackground.DoWork += new DoWorkEventHandler(execBackground_DoWork);
execBackground.RunWorkerCompleted += new RunWorkerCompletedEventHandler(execBackground_RunWorkerCompleted);
execBackground.ProgressChanged += new ProgressChangedEventHandler(execBackground_ProgressChanged);
execBackground.WorkerReportsProgress = true;
execBackground.WorkerSupportsCancellation = true;
//RUN BACKGROUNDWORKER
execBackground.RunWorkerAsync();
}
private void execBackground_DoWork(object sender, DoWorkEventArgs e)
{
myExecutor = new Executor(arg1, arg2);
myExecutor.Run();
}
private void execBackground_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("RunWorkerCompleted execBackground");
}
private void execBackground_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ExecutorProgressBar.Value += 1;
}
//TESTING
private void updateProgressBar(int i)
{
ExecutorProgressBar.Value += i;
}
public delegate void callback_updateProgressBar(int i);
Dans Exécuteur Testamentaire.cs :
public void Run()
{
string[] options = new string[2];
int i = 0;
while (LeftToRun > 0)
{
if (CurrentRunningThreads < MaxThreadsRunning)
{
BackgroundWorker myThread = new BackgroundWorker();
myThread.DoWork += new DoWorkEventHandler(backgroundWorkerRemoteProcess_DoWork);
myThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerRemoteProcess_RunWorkerCompleted);
myThread.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerRemoteProcess_ProgressChanged);
myThread.WorkerReportsProgress = true;
myThread.WorkerSupportsCancellation = true;
myThread.RunWorkerAsync(new string[2] {opt1, opt2});
//HERE ?
CurrentRunningThreads++;
i++;
LeftToRun--;
}
}
while (CurrentRunningThreads > 0) { }
logfile.Close();
MessageBox.Show("All Tasks finished");
}
private void backgroundWorkerRemoteProcess_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker myBackgroundWorker = sender as BackgroundWorker;
string[] options = (string[])e.Argument;
string machine = options[0];
string script = options[1];
//UPDATE HERE PROGRESSBAR ?
RemoteProcess myRemoteProcess = new RemoteProcess(machine, script);
string output = myRemoteProcess.TrueExec();
//UPDATE HERE PROGRESSBAR ?
this.logfile.WriteLine(output);
}
private void backgroundWorkerRemoteProcess_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CurrentRunningThreads--;
}
private void backgroundWorkerRemoteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//myExecWindow.ExecutorProgressBar.Value = e.ProgressPercentage; //TESTING
//ExecutorWindow.callback_updateProgressBar(1); //TESTING
}
EDIT 2 : je l'ai eu! Simple en fait, mais je suppose que j'ai été à la recherche de trop près pour le savoir.
Dans mon ExecutorWindow classe :
private void execBackground_DoWork(object sender, DoWorkEventArgs e)
{
myExecutor = new Executor(arg1, arg2);
myExecutor.Run(sender);
}
private void execBackground_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ExecutorProgressBar.Value += 1;
}
Et dans mon Exécuteur de la classe :
private BackgroundWorker myExecutorWindow;
[...]
public void Run(object sender)
{
myExecutorWindow = sender as BackgroundWorker;
string[] options = new string[2];
int i = 0;
while (LeftToRun > 0)
{
if (CurrentRunningThreads < MaxThreadsRunning)
{
BackgroundWorker myThread = new BackgroundWorker();
myThread.DoWork += new DoWorkEventHandler(backgroundWorkerRemoteProcess_DoWork);
myThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerRemoteProcess_RunWorkerCompleted);
myThread.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerRemoteProcess_ProgressChanged);
myThread.WorkerReportsProgress = true;
myThread.WorkerSupportsCancellation = true;
myThread.RunWorkerAsync(new string[2] {opt1, opt2});
CurrentRunningThreads++;
i++;
LeftToRun--;
}
}
[...]
private void backgroundWorkerRemoteProcess_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker myBackgroundWorker = sender as BackgroundWorker;
myBackgroundWorker.ReportProgress(1);
//PROCESSING MY STUFF HERE
myBackgroundWorker.ReportProgress(1);
}
private void backgroundWorkerRemoteProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
myExecutorWindow.ReportProgress(1);
}
Merci !
source d'informationauteur ack__ | 2011-04-26
Vous devez vous connecter pour publier un commentaire.
Vous pouvez exécuter n'importe quelle méthode sur le thread d'INTERFACE utilisateur avec cet exemple très simple
Commandes en cours d'exécution à l'intérieur du Répartiteur.Invoke(...), vous pouvez interagir avec l'INTERFACE utilisateur partir de n'importe quel thread de travail, où sinon, vous obtenez une exception.
Si vous avez vraiment besoin d'avoir le contrôle ultime sur les threads d'arrière-plan & main (UI) fil des mises à jour, voici un fantastique tutoriel: http://blog.decarufel.net/2009/03/good-practice-to-use-dispatcher-in-wpf.html
Vous devriez être en mesure d'utiliser le Répartiteur.Appeler la méthode
par exemple
Je l'ai eu! Simple en fait, mais je suppose que j'ai été à la recherche de trop près pour le savoir.
Dans mon ExecutorWindow classe :
Et dans mon Exécuteur de la classe :
J'ai trouvé un vraiment de solution simple pour créer un thread pour exécuter un bloc de code ainsi que la poignée de l'Invocation au thread principal pour modifier les propriétés du contrôle. Il fonctionne hors de la boîte .NET 4.5 et le lambda appel sur le Répartiteur pourrait être adapté pour fonctionner avec les versions antérieures de .NET. Le principal avantage est qu'il est juste, donc avec un bonheur simple et parfait quand vous avez juste besoin d'un moyen rapide de thread pour certains de base vraiment peu de code.
Donc, en supposant que vous avez une barre de progression, quelque part sur votre boîte de dialogue dans le champ d'application ce faire:
Vous devez également vous assurer que vous avez une référence à WindowsBase.dll
Si vous voulez un plus réutilisable extrait de code en cours d'exécution comme le début de fil, vous pouvez utiliser une méthode en tant que délégué, mais je trouve la ligne lambda si facile pour des tâches simples, et vous n'avez pas besoin de faire face à des événements comme avec l'arrière-plan Travailleur approches.