392 votes

Comment exécuter un simple bout de code dans un nouveau fil de discussion ?

J'ai un bout de code que je dois exécuter dans un thread différent de celui de l'interface graphique, car il provoque actuellement un gel du formulaire pendant l'exécution du code (10 secondes environ).

Supposons que je n'ai jamais créé de nouveau fil de discussion auparavant ; quel est un exemple simple/basique de la façon de le faire en C# et en utilisant .NET Framework 2.0 ou plus ?

400voto

Ed Power Points 3179

Un bon endroit pour commencer à lire est Joe Albahari .

Si vous voulez créer votre propre fil, c'est aussi simple que cela :

using System.Threading;
new Thread(() => 
{
    Thread.CurrentThread.IsBackground = true; 
    /* run your code here */ 
    Console.WriteLine("Hello, world"); 
}).Start();

195voto

Gant Points 9920

BackgroundWorker semble être le meilleur choix pour vous.

Voici mon exemple minimal. Après avoir cliqué sur le bouton, le travailleur d'arrière-plan commencera à travailler en arrière-plan et signalera sa progression simultanément. Il fera également un rapport une fois le travail terminé.

    private void button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();

        // this allows our worker to report progress during work
        bw.WorkerReportsProgress = true;

        // what to do in the background thread
        bw.DoWork += new DoWorkEventHandler(
        delegate(object o, DoWorkEventArgs args)
        {
            BackgroundWorker b = o as BackgroundWorker;

            // do some simple processing for 10 seconds
            for (int i = 1; i <= 10; i++)
            {
                // report the progress in percent
                b.ReportProgress(i * 10);
                Thread.Sleep(1000);
            }

        });

        // what to do when progress changed (update the progress bar for example)
        bw.ProgressChanged += new ProgressChangedEventHandler(
        delegate(object o, ProgressChangedEventArgs args)
        {
            label1.Text = string.Format("{0}% Completed", args.ProgressPercentage);
        });

        // what to do when worker completes its task (notify the user)
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
        delegate(object o, RunWorkerCompletedEventArgs args)
        {
            label1.Text = "Finished!";
        });

        bw.RunWorkerAsync();
    }

Note :

  • Je mets tout dans une seule méthode en utilisant la méthode anonyme de C# pour simplicité, mais vous pouvez toujours dans des méthodes différentes.
  • Il est possible de mettre à jour l'interface graphique dans ProgressChanged ou RunWorkerCompleted handlers. Cependant, la mise à jour de l'interface graphique à partir de DoWork causera InvalidOperationException .

103voto

Mark Brackett Points 46824

Le site ThreadPool.QueueUserWorkItem est assez idéal pour quelque chose de simple. Le seul problème est l'accès à un contrôle depuis l'autre fil.

System.Threading.ThreadPool.QueueUserWorkItem(delegate {
    DoSomethingThatDoesntInvolveAControl();
}, null);

85voto

TJMonk15 Points 2684

Rapide et sale, mais ça va marcher :

En utilisant en haut :

using System.Threading;

code simple :

static void Main( string[] args )
{
    Thread t = new Thread( NewThread );
    t.Start();
}

static void NewThread()
{
    //code goes here
}

Je viens d'intégrer ceci dans une nouvelle application console, à titre d'exemple.

40voto

Andy Points 15910

Essayez d'utiliser le Travailleur d'arrière-plan la classe. Vous lui donnez des délégués pour ce qui doit être exécuté, et pour être notifié lorsque le travail est terminé. Il existe un exemple sur la page MSDN que j'ai citée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X