2009-02-18 8 views
4

J'utilise multithreading dans mon code C# comme suit:Multithreading in C#: Comment passer un nom de fonction à une autre fonction pour démarrer un nouveau thread?

Thread startThread; 

public void NewThread() 
{ 
    ThreadStart starter = delegate { foo(); }; 
    startThread = new Thread(starter); 
    startThread.Start(); 
} 

private void foo() 
{ 
    //do some work 
} 

Et puis dans ma demande que j'appelle NewThread() pour exécuter le nouveau thread.

Mais maintenant j'ai beaucoup de threads sur chaque classe et chacun a un NewThread() pour lui-même, je pensais le déplacer vers une classe Util statique et lui passer le nom de la fonction chaque fois que je veux un nouveau thread sur cette fonction.

Savez-vous comment cela est la meilleure façon de le faire, si oui, comment puis-je passer le nom de la fonction en paramètre?

Répondre

4

Eh bien, puisque la méthode est privée, est-il sensé que l'appelant connaisse le nom de la méthode? Si elle était publique, vous pouvez passer la méthode:

public void NewThread(Action task) 
{ 
    ThreadStart starter = delegate { task(); }; 
    startThread = new Thread(starter); 
    startThread.Name = task.Method.Name; 
    startSpoolerThread.Start(); 
} 

public void foo() 
{ 
    //do some work 
} 

NewThread(obj.foo); 

Cependant, pour une méthode privée, je soupçonne un ENUM/commutateur est la meilleure option ...

NewThread(TasktType.Foo); 

Alternativement, vous pouvez obtenir la méthode par réflexion ...

public void NewThread(string name) 
{ 
    MethodInfo method = GetType().GetMethod(name, 
     BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
     null, Type.EmptyTypes, null); 
    ThreadStart starter = delegate { method.Invoke(this, null); }; 
    // etc (note: no point using Delegate.CreateDelegate for a 1-call usage 
1

Je vous encourage à envisager également de regarder les API de tâches CTP des extensions parallèles; vous ne mentionnez pas pourquoi vous avez besoin d'un thread, mais ils en ont automatisé une grande partie here's a link to their blog

3

À moins qu'il y ait une raison spécifique pour laquelle vous créez explicitement des threads, pourquoi ne pas utiliser le Threadpool? La méthode Threadpool.QueueUserWorkItem prend un délégué comme unité de travail à effectuer. Le délégué est un type spécifique mais vous pouvez envelopper votre propre appel de délégué dans celui-ci comme vous le faites dans votre exemple. Sauf si vous avez besoin d'un contrôle ou d'une annulation fine, il est généralement préférable d'utiliser le pool de threads plutôt que de générer des threads vous-même.

0

Sinon, si vous utilisez Win.Forms ou une application similaire basée sur une interface graphique, je vous recommande d'utiliser BackgroundWorker. Il prend soin de rassembler pour la plupart des événements liés au fil de discussion pour vous et est également beaucoup moins complexe à abandonner (si c'est quelque chose que vous devez faire).

0

Les délégués fournissent déjà une méthode pour les exécuter de manière asynchrone. Par exemple:

delegate void dowork(); 
private static void WorkDone(IAsyncResult result) 
{ 
    ((dowork)result.AsyncState).EndInvoke(result); 
    // this function is called when the delegate completes 
} 
public void Start() 
{ 
    dowork dw = delegate {// code in this block has it's own thread }; 
    dw.BeginInvoke(WorkDone, null); 
} 

Ainsi, afin de passer un pointeur de fonction à toute autre chose, vous devez créer seulement un délégué avec la signature correcte (dans ce cas, j'ai utilisé une méthode anonyme, mais vous pouvez utiliser toutes les fonctions avec le signature correcte) et appelez sa méthode BeginInvoke, en passant une fonction qui sera appelée quand elle est terminée .. cette fonction doit alors appeler EndInvoke sur le délégué d'origine, qui est passé à la fonction WorkDone dans le paramètre résultat.

Questions connexes