2016-09-27 2 views
0

Salut, j'ai créé cette classe pour me permettre facilement de faire un travail en arrière-plan mais je me bats pour faire fonctionnerCréation d'une classe ouvrière de fond avec Func et action

public static class UtilityHelper 
{ 
    private static void AssignWork<T>(this BackgroundWorker bw, Func<T> work, Action<T> completionWork = null) 
    { 
     bw.DoWork += new DoWorkEventHandler(delegate(object obj, DoWorkEventArgs args) 
      { 
       args.Result = work.Invoke(); 
      }); 
     if(completionWork != null) 
     { 
      bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object obj, RunWorkerCompletedEventArgs args) 
      { 
       completionWork.Invoke((T)args.Result); 
      }); 
     } 
    } 

    public static void RunWorkAsync<T>(Func<T> work, Action<T> completionWork = null) 
    { 
     BackgroundWorker worker = new BackgroundWorker(); 
     worker.AssignWork<T>(work, completionWork); 

     worker.RunWorkerAsync(); 
    } 

    ... 
} 

Je veux être en mesure pour appeler simplement UtilityHelper.RunWorkAsync passant dans les méthodes en tant qu'actions et func. La méthode RetrieveKnownPrinters renvoie DataTable et UpdateDataViewWithKnownPrinters possède un paramètre de DataTable.

Je suis en train de l'appeler comme UtilityHelper.RunWorkAsync<DataTable>(() => RetrieveKnownPrinters(),() => UpdateDataViewWithKnownPrinters());

Cependant, je reçois erreur Erreur 110 délégué « System.Action » ne prend pas 0 arguments parce que l'action de T prend un argument mais je ne peux pas passer un argument avec .invoke si je viens d'utiliser Action. Est-ce que quelqu'un peut m'aider avec ça?

+0

changement: UtilityHelper.RunWorkAsync (() = > RetrieveKnownPrinters(),() => UpdateDataViewWithKnownPrinters()); à: UtilityHelper.RunWorkAsync (() => RetrieveKnownPrinters(), résultat => UpdateDataViewWithKnownPrinters()); –

+2

'Action completionWork' signifie que l'action doit prendre un argument mais dans votre fonction d'appel, votre action ne prend aucun argument ('() => UpdateDataViewWithKnownPrinters() ') – Howwie

+0

' BackgroundWorker' est obsolète. Tout ce qu'il fait peut être fait avec le TPL d'une manière plus facile. Vous avez probablement besoin d'une seule boucle et d'un 'Progress '. Si vous voulez qu'une classe traite les messages en arrière-plan, vous devez utiliser 'ActionBlock ' –

Répondre

0

Vous ne pouvez pas transmettre le paramètre dans la méthode Invoke(). Semble ce que vous devez faire est d'appeler votre méthode correctement (notez le p):

UtilityHelper.RunWorkAsync<DataTable>(
     () => RetrieveKnownPrinters(), (p) => UpdateDataViewWithKnownPrinters(p)); 

EDIT: aussi vous pouvez essayer cette

UtilityHelper.RunWorkAsync<DataTable>(
     RetrieveKnownPrinters, UpdateDataViewWithKnownPrinters); 
+0

Comment le p est-il évalué par l'objet de retour de RetrieveKnownPrinters? – Emcrank

+0

Vous pouvez changer 'p' pour n'importe quoi d'autre pas de différence, je vous suggère de rechercher des expressions lambda en C# –