4

I'm trying to make a helper function to make BackgroundWorkers.

Here is what I have so far.

using System.ComponentModel;
using System;

public class BackgroundThread {

    BackgroundWorker worker;

    public BackgroundThread(Delegate workerFunction, Delegate workerCallback) {
        this.worker = new BackgroundWorker();
        this.worker.DoWork += new DoWorkEventHandler(workerFunction);
        this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(workerCallback);
    }

    public void Start(object argument) {
        this.worker.RunWorkerAsync(argument);
    }
}

Although I am getting this error.

Expression denotes a 'variable', where a 'type' or 'method group' was expected

It makes sense since normally you pass a reference to a function to the Handlers but I don't know how to do it in this context. Or is this just not possible. I don't know enough about C# delegates and such to know what to do.

2 Answers 2

3

Like this?

public class BackgroundThread
{

    System.ComponentModel.BackgroundWorker worker;

    public BackgroundThread(System.ComponentModel.DoWorkEventHandler workerFunction, System.ComponentModel.RunWorkerCompletedEventHandler workerCallback)
    {
        this.worker = new System.ComponentModel.BackgroundWorker();
        this.worker.DoWork += workerFunction;
        this.worker.RunWorkerCompleted += workerCallback;
    }

    public BackgroundThread(Action<object> anyWorkFunctionWithObjectArgument, Action<object> anyCallback)
    {
        this.worker = new System.ComponentModel.BackgroundWorker();
        this.worker.DoWork += (sender, e) => { anyWorkFunctionWithObjectArgument.Invoke(e.Argument); };
        this.worker.RunWorkerCompleted += (sender, e) => { anyCallback.Invoke(e.Result); };
    }

    public void Start(object argument)
    {
        this.worker.RunWorkerAsync(argument);
    }

    public static BackgroundThread GetDoNothingInstance()
    {
        return new BackgroundThread(
            (sender, e) =>
            {
                // e is DoWorkEventArgs
            },
            (sender, e) =>
            {
                // e is RunWorkerCompletedEventArgs
            });
    }

    public static BackgroundThread GetDoNothingInstance2()
    {
        Action<object> workfunction = delegate(object argument)
        {
            // Do nothing
        };

        Action<object> callback = delegate(object result) 
        { 
            // Do nothing
        };

        return new BackgroundThread(workfunction, callback);       
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

This, like Sully's, I did think of. But this requires the instantiation of the Handlers outside of the BackgroundThread class in my case. Now if this is the way it has to be done, so be it. I was just hoping for a way to do it inside the constructor.
Both of you used the same approach but I do like this one better since it keeps everything in the constructor. Thank you for your help.
I like this one better too :) I knew there was probably a cleaner way to write this. Nice job eric.
2

Just saw your comment. This should allow you to just pass a "plain old function" without having to shape it like a handler:

class Program
{
    protected static void plainOldWorkerFunction(object argument)
    {
        return;
    }

    protected static void plainOldCallbackFunction()
    {
        return;
    }

    static void Main(string[] args)
    {
        BackgroundThread bt = new BackgroundThread(plainOldWorkerFunction, plainOldCallbackFunction);

        bt.Start(1234);
    }
}

public class BackgroundThread
{
    BackgroundWorker worker;
    Action<object> workerAction;
    Action callbackAction;

    protected void doWork(object sender, DoWorkEventArgs e)
    {
        workerAction(e.Argument);
    }

    protected void callback(object sender, RunWorkerCompletedEventArgs e)
    {
        callbackAction();
    }

    public BackgroundThread(Action<object> workerFunction, Action workerCallback)
    {
        this.workerAction = workerFunction;
        this.callbackAction = workerCallback;

        this.worker = new BackgroundWorker();
        this.worker.DoWork += doWork;
        this.worker.RunWorkerCompleted += callback;
    }

    public void Start(object argument)
    {
        this.worker.RunWorkerAsync(argument);
    }
}

Original answer:

Try this constructor instead:

public BackgroundThread(DoWorkEventHandler workerFunction, RunWorkerCompletedEventHandler workerCallback)
{
    this.worker = new BackgroundWorker();
    this.worker.DoWork += workerFunction;
    this.worker.RunWorkerCompleted += workerCallback;
}

And just make sure your workerFunction and workerCallback have these parameters:

protected static void workerFunction (object sender, DoWorkEventArgs e)
{
    return;
}

protected static void workerCallback (object sender, RunWorkerCompletedEventArgs e)
{
    return;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.