Emcrank Emcrank - 2 months ago 9
C# Question

Creating a background worker class with Func and Action

Hi I have created this class to easily allow me to do some work in the background however I am struggling to get it to work

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

...
}


I want to be able to just call
UtilityHelper.RunWorkAsync
passing in the methods as actions and func's.
The RetrieveKnownPrinters method returns DataTable and the UpdateDataViewWithKnownPrinters has one parameter of DataTable.

I am trying to call it like
UtilityHelper.RunWorkAsync<DataTable>(() => RetrieveKnownPrinters(), () => UpdateDataViewWithKnownPrinters());


However I am getting error Error 110 Delegate 'System.Action' does not take 0 arguments because Action of T takes one argument however I cannot pass an argument with .Invoke if i just use Action. Can anyone help me with this?

Answer

You cannot pass the parameter in the Invoke() method. Seems what you need to do is just call your method properly (notice the p):

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

EDIT: also you may try this

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