2011-09-29 5 views
2

Ce que j'essaie de faire est de pouvoir transmettre une référence de fonction à une autre fonction et de l'utiliser comme méthode de rappel pour un System.Threading.ThreadPool.QueueUserWorkItem.Méthode de rappel dynamique pour System.Threading.ThreadPool.QueueUserWorkItem C#

Voir dans la méthode D() le paramètre 'Any'.

Je dois être en mesure de passer le pointeur ou la référence de méthode de rappel pour le paramètre 'Any'. Je ne peux pas utiliser un délégué, car cela devrait être statique, n'est-ce pas?

Des idées?

private void A() { /*code*/ } 

    private void B() { /*code*/ } 

    private void C(int i) 
    { 
     switch(i) 
     { 
      case 1: 
       D(A()); 
       break; 
      case 2: 
       D(B()); 
       break; 
      default: 
       break; 
     } 
    } 

    private void D(type? Any) 
    { 
     System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Any)); 
    } 

Répondre

2

Je pense que cela va faire ce que vous voulez, mais WaitCallback délégués prennent un objet en tant que paramètre.

 private void A(object state) 
    { 
     // does one thing 
    } 

    private void B(object state) 
    { 
     // does a different thing 
    } 

    private void C(int i) 
    { 
     switch (i) 
     { 
      case 1: 
       D(new System.Threading.WaitCallback(A)); 
       break; 
      case 2: 
       D(new System.Threading.WaitCallback(B)); 
       break; 
      default: 
       break; 
     } 
    } 

    private void D(System.Threading.WaitCallback worker) 
    { 
     System.Threading.ThreadPool.QueueUserWorkItem(worker); 
    } 
+0

Merci, C'est exactement ce dont j'avais besoin. – M3NTA7

+0

Le compilateur va tourner '(A)' dans '(nouveau WaitCallback (A))' pour vous. –

+0

Oui, je suis juste vieille école. J'aime savoir ce qui se passe. J'aime le type de var cependant, gagne le temps et juste au clair. – Damon8or

3

Je ne peux pas utiliser un délégué, parce qu'il faudrait être statique, est-ce exact.

Non, ce n'est pas correct.

delegate void MyMethods(); 

class Foo 
{ 
    void Minstance() {} 
    static void Mstatic() {} 

    MyMethods m1 = Minstance; // OK 
    MyMethods m2 = Mstatic; // OK 
} 

Et ce qui suit est une syntaxe incorrecte:

 case 1: 
      D(A()); // here you call (execute) A 
      break; 

omettre que la parenthèse après la méthode:

 case 1: 
      D(A); // this passes a reference to A 
      break; 

Et maintenant, vous devez bien définir D:

void D(WaitCallback any) 
{ 
     ThreadPool.QueueUserWorkItem(any); 
} 
0

Oui, vous voulez utiliser un légat:

public void CallbackDelegate(); 

private void D(CallbackDelegate D) 
{ 
} 
0

Peut-être que cela pourrait aider:

private void D(Delegate any) 
     {  
      System.Threading.ThreadPool.QueueUserWorkItem(ignored => any.DynamicInvoke()); 
     } 
0

Essayez d'utiliser un délégué comme ici. S'il vous plaît demandez-moi si vous avez des questions.

using System; 
using System.Threading; 

namespace Thread.Pool.Test 
{ 
    delegate void VoidDelegate (object obj); 

    public class Delegate 
    { 
     /// <summary> 
     /// ThreadPool Entry Point for A 
     /// </summary> 
     /// <param name='obj'> 
     /// EventWaitHandle 
     /// </param> 
     /// <exception cref='ArgumentException'> 
     /// Is thrown when an argument passed to a method is invalid. 
     /// </exception> 
     private void A (object obj) { 
      if (!(obj is EventWaitHandle)) 
       throw new ArgumentException ("Only EventWaitHandle supported!"); 
      A ((EventWaitHandle)obj); 
     } 

     private void A (EventWaitHandle handle) { 
      // does one thing 

      //finsihed 
      handle.Set(); 
     } 

     /// <summary> 
     /// ThreadPool Entry Point for B 
     /// </summary> 
     /// <param name='obj'> 
     /// EventWaitHandle 
     /// </param> 
     /// <exception cref='ArgumentException'> 
     /// Is thrown when an argument passed to a method is invalid. 
     /// </exception> 
     private void B (object obj) { 
      if (!(obj is EventWaitHandle)) 
       throw new ArgumentException ("Only EventWaitHandle supported!"); 
      B ((EventWaitHandle)obj); 

     } 

     private void B (EventWaitHandle handle) { 
      // does a different thing 

      //finsihed 
      handle.Set(); 
     } 

     private void C (int i) { 
      EventWaitHandle waitHandle = new ManualResetEvent (false); 
      switch (i) { 
      case 1: 
       D (A ,waitHandle); 
       break; 
      case 2: 
       D (B ,waitHandle); 
       break; 
      default: 
       throw new Exception ("Case not supported"); 
      } 
      //Wait for the thread to finish 
      waitHandle.WaitOne(); 
     } 

     private void D (VoidDelegate any, EventWaitHandle waitHandle) { 
      ThreadPool.QueueUserWorkItem (new System.Threading.WaitCallback (any),waitHandle); 
     } 

    } 
} 
+0

Merci, je vais devoir passer par dessus quand j'ai plus de temps. – M3NTA7