Lassen Sie einen BackgroundWorker mehrere Vorgänge nacheinander ausführen, ohne das Formular einzufrieren

Ich habe bereits eine ähnliche Frage gestelltHier aber ich habe jetzt eine folgefrage.

Ich muss das externe Programm mehrmals hintereinander starten, habe aber mehrere Probleme damit:

Es wurde versucht, alle Operationen gleichzeitig zu starten. Ich habe ein leeres "while (bgwkSVN.IsBusy) {}" eingefügt, es funktioniert ein bisschen, aber ich bin mir ziemlich sicher, dass es einige von Ihnen zum Weinen bringen wird.Das Formular wird weiterhin eingefroren, solange nicht alle Vorgänge abgeschlossen sind. In Anbetracht einiger anderer SO-Themen denke ich, dass die Art und Weise, wie mein Code geschrieben ist, die Anwendung nicht wirklich multithreaded ist oder ich sie nicht ausnütze ... aber ich bin wirklich nicht mit Threading vertraut.Es scheint nicht das zu tun, was ich von ihm verlange. Ich werde versuchen, mit einer einfacheren Operation herauszufinden, ob die Operation nicht erfolgreich ist oder ob der Backgroundworker niemals gestartet wird.

Hier ist der Code (sorry, es ist ein bisschen lang):

private struct svnCommand
{
    public svnCommand(string args, string path, int pourcent)
    {
        this.args = args;
        this.path = path;
        this.pourcent = pourcent;
    }
    public string args;
    public string path;
    public int pourcent;
}

private BackgroundWorker bgwkSVN;

public Merger()
{
    InitializeComponent();
    InitializeBackgroundWorker();
    this.textBoxCheminRacine.Text = cheminRacine;
}

private void MergerRevisions(object sender, EventArgs e)
{

    activerControles(false);

    textBoxOutput.Text = "";
    cheminRacine = textBoxCheminRacine.Text;
    if (!cheminRacine.EndsWith("\\")) { cheminRacine = cheminRacine + "\\"; }

    string branchToMerge = this.textBoxBranche.Text;
    if (branchToMerge.StartsWith("/")) { branchToMerge = branchToMerge.Substring(1); }

    // révision(s)
    string revisions = "";
    foreach (string r in textBoxRevision.Text.Split(','))
    {
        int rev;
        if (int.TryParse(r, out rev))
        {
            revisions += string.Format(" -r {0}:{1}", rev - 1, rev);
        }
        else
        {
            revisions += " -r " + r.Replace("-", ":");
        }
    }

    // pourcentage de complétion pour chaque étape
    int stepPourcent = (int)Math.Floor((double)(100 / (3 + Directory.GetDirectories(cheminRacine + "branches").Length)));

    // merge sur le trunk
    while (bgwkSVN.IsBusy) { }
    bgwkSVN.RunWorkerAsync(new svnCommand(string.Format("merge --accept postpone {0} {1}{2} .", revisions, svnbasepath, branchToMerge), cheminRacine + "trunk", stepPourcent));


    // merge sur chaque branche
    string[] branches = Directory.GetDirectories(cheminRacine + "branches");
    foreach (string b in branches)
    {
        while (bgwkSVN.IsBusy) { }
        bgwkSVN.RunWorkerAsync(new svnCommand(string.Format("merge --accept postpone {0} {1}{2} .", revisions, svnbasepath, branchToMerge), b, stepPourcent));
    }

    // virer les mergeinfo
    while (bgwkSVN.IsBusy) { }
    bgwkSVN.RunWorkerAsync(new svnCommand("pd svn:mergeinfo . -R", cheminRacine, stepPourcent));

    // svn update
    while (bgwkSVN.IsBusy) { }
    bgwkSVN.RunWorkerAsync(new svnCommand("update", cheminRacine, stepPourcent));

    textBoxOutput.Text += Environment.NewLine + "Terminé.";
    MessageBox.Show("Merge terminé.", "Merge terminé", MessageBoxButtons.OK);

    // réactiver les champs et boutons
    activerControles(true);
}

/// <summary>
/// Set up the BackgroundWorker object by attaching event handlers
/// </summary>
private void InitializeBackgroundWorker()
{
    bgwkSVN = new BackgroundWorker();
    bgwkSVN.WorkerReportsProgress = true;
    bgwkSVN.WorkerSupportsCancellation = true;
    bgwkSVN.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    bgwkSVN.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    bgwkSVN.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}

/// <summary>
/// Exécuter une commande SVN
/// </summary>
private string SVNcmd(svnCommand s, BackgroundWorker worker, DoWorkEventArgs e)
{
    string o = "";
    o += s.path + Environment.NewLine + s.args + Environment.NewLine;

    if (worker.CancellationPending)
    {
        e.Cancel = true;
    }
    else
    {
        Process p = new Process();
        p.StartInfo.WorkingDirectory = s.path;
        p.StartInfo.FileName = "svn";
        p.StartInfo.Arguments = s.args;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.UseShellExecute = false;
        p.Start();
        o += p.StandardOutput.ReadToEnd() + Environment.NewLine;
        p.WaitForExit();

        if (s.pourcent > 0)
        {
            worker.ReportProgress(s.pourcent);
        }
    }
    return o;
}


/// <summary>
/// Where the actual, potentially time-consuming work is done.
/// </summary>
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    // Get the BackgroundWorker that raised this event.
    BackgroundWorker worker = sender as BackgroundWorker;

    // Assign the result of the computation to the Result property of the DoWorkEventArgs
    // object. This is will be available to the RunWorkerCompleted eventhandler.
    e.Result = SVNcmd((svnCommand)e.Argument, worker, e);
}

/// <summary>
/// Deals with the results of the background operation
/// </summary>
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // First, handle the case where an exception was thrown.
    if (e.Error != null)
    {
        MessageBox.Show(e.Error.Message);
    }
    else if (e.Cancelled)
    {
        textBoxOutput.Text += Environment.NewLine + "Annulé.";
    }
    else
    {
        textBoxOutput.Text += e.Result.ToString();
    }
}

/// <summary>
/// Updates the progress bar
/// </summary>
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.progressBarTraitement.Value += e.ProgressPercentage;
}

Vielen Dank !

Antworten auf die Frage(4)

Ihre Antwort auf die Frage