2012-02-10 2 views
2

Je veux mettre en file d'attente une liste de tâches, puis effectuer un certain événement. Code:Transférer le délégué avec le paramètre à une fonction

internal class MyClass 
{ 
    private Queue<Task> m_taskQueue; 

    protected MyClass() 
    { 
     m_taskQueue = new Queue<Task>(); 
    } 

    public delegate bool Task(object[] args); 

    public void EnqueueTask(Task task) 
    { 
     m_taskQueue.Enqueue(task); 
    } 

    public virtual bool Save() 
    { 
     // save by processing work queue 
     while (m_taskQueue.Count > 0) 
     { 
      var task = m_taskQueue.Dequeue(); 
      var workItemResult = task.Invoke(); 

      if (!workItemResult) 
      { 
       // give up on a failure 
       m_taskQueue.Clear(); 
       return false; 
      }     
     } 
     return true; 
    } 
} 

Chaque tâche déléguée peut avoir sa propre liste de paramètres: Task (object [] args). Ma question est comment passer le paramètre à chaque tâche pour la file d'attente de tâches?

+2

Passez quel paramètre? Vous n'avez pas vraiment expliqué ce que vous essayez de faire ... –

+0

@Jon, clarifié dans la question. – Icerman

+1

Pas vraiment ... vous avez dit que chaque tâche aura sa propre liste de paramètres, mais vous n'avez rien dit sur l'endroit où vous attendez d'obtenir ces données. –

Répondre

4

D'accord, nous avons maintenant un peu plus d'informations, il semble que votre méthode EnqueueTask devrait effectivement ressembler à ceci:

public void EnqueueTask(Task task, object[] values) 

droit?

Pour commencer j'éviter d'utiliser le nom Task, qui fait déjà partie du noyau de .NET 4 et deviendront très de premier plan dans .NET 5. Comme Josué dit, vous avez essentiellement obtenu un Func<object[], bool> .

Ensuite, vous pouvez garder deux listes - une pour les délégués et une pour les valeurs, mais il est plus facile de garder un Queue<Func<bool>> comme ceci:

private readonly Queue<Func<bool>> taskQueue = new Queue<Func<bool>>(); 


public void EnqueueTask(Task task, object[] values) 
{ 
    taskQueue.Enqueue(() => task(values)); 
} 

Ensuite, le reste de votre code fait travailler "tel quel". L'expression lambda capturera values et task, donc lorsque vous appellerez le Func<bool>, il fournira ces valeurs au délégué d'origine.

+0

Oui, c'était mon intention. C'est exactement ce dont j'ai besoin. Un mineur, je pense que Add() doit être remplacé par Queue(). – Icerman

+0

@Icerman: Yup, fait. –

1

Pour une bonne compréhension de votre question, vous transmettez simplement l'information comme un appel normal. Avez-vous envisagé d'utiliser Func? Vous pouvez simplement passer des arguments au Task.Invoke, c'est-à-dire Task.Invoke([arguments here as a *single* object array]).

object[] arguments = null; // assign arguments to something 
var workItemResult = task.Invoke(arguments); 

Ci-dessous un exemple avec le type Func.

internal class MyClass 
    { 
     private Queue<Func<object[], bool>> m_taskQueue; 

     protected MyClass() 
     { 
      m_taskQueue = new Queue<Func<object[], bool>>(); 
     } 



     public void EnqueueTask(Func<object[], bool> task) 
     { 
      m_taskQueue.Enqueue(task); 
     } 

     public virtual bool Save() 
     { 
      object[] arguments = null; // assign arguments to something 
      // save by processing work queue 
      while (m_taskQueue.Count > 0) 
      { 
       var task = m_taskQueue.Dequeue(); 
       var workItemResult = task(arguments); 

       if (!workItemResult) 
       { 
        // give up on a failure 
        m_taskQueue.Clear(); 
        return false; 
       } 
      } 
      return true; 
     } 
    } 
+0

Ma question est de garder les paramètres de Enqueue() de l'appelant, puis traiter ces tâches avec les paramètres transmis. – Icerman

+0

Les paramètres font partie de la signature de la fonction que vous ne transmettez pas un paramètre à une fonction. Les arguments sont les "valeurs" réelles que vous transmettez lorsque vous appelez une fonction. Voulez-vous dire que vous voulez sauvegarder les arguments et appeler ensemble? Si c'est le cas, placez votre Delegate et un objet object [] ensemble dans une nouvelle classe, puis mettez en file d'attente une instance de cette nouvelle classe, puis, après Dequeue, invoquez le délégué avec l'objet [] dans la classe. –

+0

Oui, l'argument est ce que je voulais dire. Votre suggestion est ce que j'ai vu dans d'autres échantillons. Vous vous demandez s'il y a d'autres moyens. – Icerman

Questions connexes