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 ?

14voto

Si vous voulez obtenir une valeur :

var someValue;

Thread thread = new Thread(delegate()
            {                 
                //Do somthing and set your value
                someValue = "Hello World";
            });

thread.Start();

while (thread.IsAlive)
  Application.DoEvents();

6voto

Redbaron Points 523

Mettez ce code dans une fonction (le code qui ne peut pas être exécuté sur le même thread que l'interface graphique), et pour déclencher l'exécution de ce code, mettez ce qui suit.

Thread myThread= new Thread(nameOfFunction);

workerThread.Start();

L'appel de la fonction start sur l'objet thread provoquera l'exécution de votre appel de fonction dans un nouveau thread.

4voto

Matt Davison Points 1276
// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime, 
                                            DateTime procDateTime);

// following inside of some client method 

    GetEnergyUsageDelegate nrgDel = GetEnergyUsage;                     
    IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
    while (!aR.IsCompleted) Thread.Sleep(500);
    int usageCnt = nrgDel.EndInvoke(aR);

Charles, votre code (ci-dessus) n'est pas correct. Vous n'avez pas besoin de faire tourner l'attente de l'achèvement. EndInvoke bloquera jusqu'à ce que le WaitHandle soit signalé.

Si vous voulez bloquer jusqu'à l'achèvement, il vous suffit de

nrgDel.EndInvoke(nrgDel.BeginInvoke(lastRuntime,procDT,null,null));

ou alternativement

ar.AsyncWaitHandle.WaitOne();

Mais quel est l'intérêt d'émettre des appels anyc si vous bloquez ? Vous pourriez tout aussi bien utiliser un appel synchrone. Un meilleur choix serait de ne pas bloquer et de passer dans une lambda pour le nettoyage :

nrgDel.BeginInvoke(lastRuntime,procDT,(ar)=> {ar.EndInvoke(ar);},null);

Une chose à garder à l'esprit est que vous doit appeler EndInvoke. Beaucoup de gens oublient cela et finissent par laisser échapper le WaitHandle, car la plupart des implémentations asynchrones libèrent le waithandle dans EndInvoke.

4voto

user50612 Points 1921

Si vous comptez utiliser l'objet Thread brut, vous devez définir IsBackground à true au minimum et vous devez également définir le modèle d'appartement du Threading (probablement STA).

    public static void DoWork()
    {
        // do some work
    }

    public static void StartWorker()
    {
        Thread worker = new Thread(DoWork);
        worker.IsBackground = true;
        worker.SetApartmentState(System.Threading.ApartmentState.STA);
        worker.Start()              
    }

Je recommande la classe BackgroundWorker si vous avez besoin d'une interaction avec l'interface utilisateur.

1voto

Charles Bretana Points 59899

Une autre option, qui utilise les délégués et le Thread Pool...

supposant que 'GetEnergyUsage' est une méthode qui prend une DateTime et une autre DateTime comme arguments d'entrée, et retourne un Int...

// following declaration of delegate ,,,
public delegate long GetEnergyUsageDelegate(DateTime lastRunTime, 
                                            DateTime procDateTime);

// following inside of some client method 
GetEnergyUsageDelegate nrgDel = GetEnergyUsage;                     
IAsyncResult aR = nrgDel.BeginInvoke(lastRunTime, procDT, null, null);
while (!aR.IsCompleted) Thread.Sleep(500);
int usageCnt = nrgDel.EndInvoke(aR);

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