0
votes

C # - Mise à jour des éléments Formulaires Windows du fil

Je crée actuellement un programme pour sauvegarder les ordinateurs portables vers un bâton USB. J'ai créé une classe à partir de laquelle je appelle des méthodes. Je commence ensuite la sauvegarde réelle via un fil séparé. Pour le moment, j'essaie de changer une zone de texte et une barre de progression via ce fil. Cependant, il ne montre toujours que le premier changement immédiatement et les autres progrès que lorsque le programme a traversé. J'ai essayé plusieurs solutions d'Internet, mais rien n'a travaillé jusqu'à présent. Peut-être que quelqu'un a une solution ici.

    backup sales_backup = new backup();

    //Start Backup Button
    private void backup_button_Click(object sender, EventArgs e)
    {
        Thread backupprocess = new Thread(new 
        ThreadStart(sales_backup.backup_start));
        backupprocess.Start();
    }

    //Backup Function
        public void backup_start()
        {
            files_to_copy = 0;
            files_copied = 0;

            var principalForm = System.Windows.Forms.Application.OpenForms.OfType<Form1>().FirstOrDefault();

            if (principalForm.drive_selector.SelectedItem != null)
            {
                //Set Parameters
                principalForm.backup_button.Visible = false;
                error_copy = false;
                error_message = "";
                device_removed = false;

                //Fill variables
                string temp = principalForm.drive_selector.SelectedItem.ToString();
                temp = regex_matching_return_match(temp, @"[A-Z,a-z](:\\)");
                backup_device = temp;

                //Set Backup device size
                for (int i = 0; i < backup_devices_list.Count; i++)
                {
                    if (backup_devices_list[i].backup_device_name == temp)
                    {
                        backup_device_size = backup_devices_list[i].device_size;
                        file_system = backup_devices_list[i].file_system;
                        double temp_free = calculate_GB(backup_devices_list[i].device_free_space.ToString());
                        device_free_space = temp_free;
                        break;
                    }
                }

                //If no device is initialized
                if (backup_device == null || backup_device_size == 0)
                {
                    write_to_textbox(get_create_usb_instance_error(), "red");
                }
                else //If select ist successfull
                {
                    //Get Backup size
                    get_size();
                    if (backup_size < device_free_space)
                    {
                        backup_path_target = backup_device + "\\Backup\\";
                        Directory.CreateDirectory(backup_path_target);

                        //Get file count
                        get_file_count();

                        //Create Copy job
                        for (int i = 0; i < backup_path_source.Length; i++)
                        {
                            string backup_path_s = backup_path_source[i] + "\\";
                            string backup_path_t = backup_path_target + backup_path_target_folders[i] + "\\";
                            copy_function(backup_path_s, backup_path_t);
                            int progress = return_progress();
                            TextBox test = principalForm.textBox2;
                            ProgressBar progress_bar = principalForm.progressBar1;
                            //Delegate Textbox
                            if (test.InvokeRequired)
                            {
                                test.Invoke(new Action(() => test.Text = "Copying: " + backup_path_t));
                            }
                            else
                            {
                                test.Text = "Copying: " + backup_path_t;
                            }
                            //Delegate Progressbar
                            if (progress_bar.InvokeRequired)
                            {
                                test.Invoke(new Action(() => progress_bar.Value = progress));
                            }
                            else
                            {
                                progress_bar.Value = progress;
                            }
                        }


2 commentaires

Vous ne pouvez pas mettre à jour l'interface utilisateur à partir d'un fil d'arrière-plan. Vous pas besoin invoke soit, si vous utilisez async / attendre et le processus processus Signaler des progrès sur d'autres threads


Si vous utilisez une tâche .Run et async / attendre Vous n'aurez pas à utiliser invoke (). . Invoke Blocks Si le fil de l'interface utilisateur est occupé. Vous devez également séparer l'interface utilisateur du code de traitement de fichier. Il n'est pas nécessaire d'accéder à la forme principale comme celle-ci lorsque vous pouvez passer des lecteurs, etc. comme paramètres de la méthode


3 Réponses :


0
votes

Assurez-vous que vous faites la mise à jour du bon fil. GUI ne peut être mis à jour que de son propre fil. Plus ici .


0 commentaires

-1
votes

Avez-vous essayé d'utiliser progress_bar.invoke ((méthodalvoke) (() => progres_bar.value = avancement));


2 commentaires

Ce n'est pas une réponse. Il devrait être supprimé. S'il vous plaît gagner les 50 points REP pour poster des commentaires.


Changer le type de délégué ne changera pas ce qui est invoqué. Le code pourrait être progress_bar.invoke ((() => progress_bar.value = progrès); .



0
votes

Je ne pouvais pas tester cela, mais cela devrait au moins vous aider à y arriver:

private void InvokeIfRequired<C>(C control, Action<C> action) where C : Control
{
    if (control.InvokeRequired)
    {
        control.Invoke((Action)(() => action(control)));
    }
    else
    {
        action(control);
    }
}

private void backup_button_Click(object sender, EventArgs e)
{
    var principalForm = System.Windows.Forms.Application.OpenForms.OfType<Form1>().FirstOrDefault();
    if (principalForm.drive_selector.SelectedItem != null)
    {
        principalForm.backup_button.Visible = false;

        string temp = principalForm.drive_selector.SelectedItem.ToString();

        TextBox test = principalForm.textBox2;
        ProgressBar progress_bar = principalForm.progressBar1;

        Action<string> updateTest = t => this.InvokeIfRequired<TextBox>(test, c => c.Text = t);
        Action<int> updateProgress = v => this.InvokeIfRequired<ProgressBar>(progress_bar, c => c.Value = v);

        Thread backupprocess = new Thread(new ThreadStart(() => sales_backup.backup_start(temp, updateTest, updateProgress)));
        backupprocess.Start();
    }
}

//Backup Function
public void backup_start(string temp, Action<string> updateTest, Action<int> updateProgress)
{
    files_to_copy = 0;
    files_copied = 0;

    //Set Parameters

    error_copy = false;
    error_message = "";
    device_removed = false;

    //Fill variables
    temp = regex_matching_return_match(temp, @"[A-Z,a-z](:\\)");
    backup_device = temp;

    //Set Backup device size
    for (int i = 0; i < backup_devices_list.Count; i++)
    {
        if (backup_devices_list[i].backup_device_name == temp)
        {
            backup_device_size = backup_devices_list[i].device_size;
            file_system = backup_devices_list[i].file_system;
            double temp_free = calculate_GB(backup_devices_list[i].device_free_space.ToString());
            device_free_space = temp_free;
            break;
        }
    }

    //If no device is initialized
    if (backup_device == null || backup_device_size == 0)
    {
        write_to_textbox(get_create_usb_instance_error(), "red");
    }
    else //If select ist successfull
    {
        //Get Backup size
        get_size();
        if (backup_size < device_free_space)
        {
            backup_path_target = backup_device + "\\Backup\\";
            Directory.CreateDirectory(backup_path_target);

            //Get file count
            get_file_count();

            //Create Copy job
            for (int i = 0; i < backup_path_source.Length; i++)
            {
                string backup_path_s = backup_path_source[i] + "\\";
                string backup_path_t = backup_path_target + backup_path_target_folders[i] + "\\";
                copy_function(backup_path_s, backup_path_t);
                int progress = return_progress();

                //Delegate Textbox
                updateTest("Copying: " + backup_path_t);

                //Delegate Progressbar
                updateProgress(progress);
            }
        }
    }
}


0 commentaires