2016-09-27 7 views
0

Привет Я создал этот класс легко позволит мне сделать какую-то работу в фоновом режиме, однако я изо всех сил, чтобы заставить его работатьСоздание класса фона рабочего с Func и действий

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(); 
    } 

    ... 
} 

Я хочу, чтобы иметь возможность просто позвоните UtilityHelper.RunWorkAsync, переходя в методы как действия и func's. Метод RetrieveKnownPrinters возвращает DataTable, а UpdateDataViewWithKnownPrinters имеет один параметр DataTable.

Я пытаюсь назвать это как UtilityHelper.RunWorkAsync<DataTable>(() => RetrieveKnownPrinters(),() => UpdateDataViewWithKnownPrinters());

Однако я получаю ошибки Ошибки 110 делегата «System.Action» не принимает 0 аргументов, потому что действие Т принимает один аргумент, однако я не могу передать аргумент с .Invoke если я просто использую действие. Кто-нибудь может мне с этим помочь?

+0

изменение: UtilityHelper.RunWorkAsync (() = > RetrieveKnownPrinters(),() => UpdateDataViewWithKnownPrinters()); : UtilityHelper.RunWorkAsync (() => RetrieveKnownPrinters(), result => UpdateDataViewWithKnownPrinters()); –

+2

'Действие completeWork' означает, что действие должно принимать один аргумент, но в вашей вызывающей функции ваше действие не принимает никаких аргументов ('() => UpdateDataViewWithKnownPrinters() ') – Howwie

+0

' BackgroundWorker' устарело. Все, что он делает, может быть сделано с помощью TPL более простым способом. Вам, вероятно, нужен один цикл и «Прогресс ». Если вы хотите, чтобы один класс обрабатывал сообщения в фоновом режиме, вы должны использовать 'ActionBlock ' –

ответ

0

Вы не можете передать параметр в методе Invoke(). Кажется, что вам нужно сделать, это просто вызвать ваш метод правильно (обратите внимание на p):

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

EDIT: также вы можете попробовать это

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

Как оценивается p для возвращаемого объекта RetrieveKnownPrinters? – Emcrank

+0

Вы можете изменить 'p' ни на что другое, не предлагая вам искать лямбда-выражения в C# –