13 messaggi dal 17 dicembre 2005
C'è un comportamento che non mi è chiaro del BackgroundWorker: in alcuni casi, durante l'esecuzione sembra che la Form non risponda più al click del mouse.

Nel mio esempio ho un BackgroundWorker che viene avviato dal tasto Start e che può essere interrotto dal tasto Stop.
Apparentemente funziona tutto, però se all'interno di ProgressChanged faccio cose troppo complicate, allora la Form sembra
che non risponda più e quindi non posso neppure premere il tasto Stop per interrompere il BackgroundWorker.

In realtà, ho anche trovato un modo per farlo comunque funzionare: inserendo all'interno del DoWork una istruzione:
System.Threading.Thread.Sleep(MsSleep); 

con un MsSleep abbastanza alto, in questo modo tutto funziona.

Premesso che che all'interno di ProgressChanged sarebbe bene fare poche cose, comunque a me il comportamento mi sembra un po' strano, forse sbaglio io qualche cosa?


Per simulare il problema, ho fatto un piccolo programma con 2 variabili:
MsSleep per impostare i millisecondi dello sleep
NumLoop per simulare delle operazioni complicate all'interno di ProgressChanged

I risultati sono:
     //MsSeep=1   NumLoop=100    ok
     //MsSeep=1   NumLoop=1000   La Form non risponde al click
     //MsSeep=100 NumLoop=1000   ok


qui il programma di esempio:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
            this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
        }

        private int MsSleep = 100;
        private int NumLoop = 1000;
        //MsSeep=1   NumLoop=100    ok
        //MsSeep=1   NumLoop=1000   La Form non risponde al click
        //MsSeep=100 NumLoop=1000   ok

        private void Form1_Load(object sender, EventArgs e)
        {
            this.backgroundWorker1.WorkerReportsProgress = true;
            this.backgroundWorker1.WorkerSupportsCancellation = true;
        }


        private void button_Start_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void button_Stop_Click(object sender, EventArgs e)
        {
            backgroundWorker1.CancelAsync();
        }
        
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int i_max = 10000;
            for (int i = 1; i< i_max; i++)
            {
                double pd = (double)i / (double)i_max*100;
                int pi = (int)pd;
                backgroundWorker1.ReportProgress(pi);
                if (backgroundWorker1.CancellationPending) break;
                System.Threading.Thread.Sleep(MsSleep);
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            for (int i = 1; i < NumLoop; i++)
            {
                this.Text = e.ProgressPercentage.ToString() + "    " +  DateTime.Now.Millisecond.ToString();
            }
            this.Refresh();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.Text = "OK";
        }

    }
}

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.