views:

64

answers:

5

I am using a backgroundworker that can have n instances. Problem is the DoWork method (that has the 'sender' parameter which is the BackgroundWorker) calls other code that produces a callback - thus i dont have the sender.

How can i determine the BackgroundWorker that the current code is running under?

ex:

private void SetupThread()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(DoTheWork);
}


private void DoTheWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{

    // I know that sender here can be converted, but thats no good for me
    MyClass.DoSomething(); // This will produce a callback(event) from MyClass
}

private void MethodCalledFromEventCallback()
{
   // Here is where the actual work is being done.  I need to determine which
   // instance of the Backgroundworker is calling it so that i can use the         
   // UpdateProgress method

  // I cannot do this :-(  (BackgroundWorker)System.Threading.Thread.CurrentThread;

}

Im probably just overlooking something (unless threadpool is in order :-( )

Im sure this is easily doable with the BackgroundWorker ... any ideas?


edit

I caused some confusion in my description, here are some more facts :-) 1.) I already call the bw.RunWorkerAsync() 2.) The class that invokes the event MethodCalledFromEventCallback has no knowledge of the background thread 3.) I cannot (due to design requirements) include the Backgroundworker as a parameter

Thanks :-)

+1  A: 

Could you just send the "sender" along as a parameter to the callback, and get at the BGW that way?

Robert Iver
+1  A: 

You want to use the RunWorkerAsync method that takes an argument, which is then available as the Argument property of the event parameter.

You could then pass the BackgroundWorker instance to the background method.

Lasse V. Karlsen
+2  A: 
BackgroundWorker.RunWorkerAsync(bw);
Jonathan Allen
The final block that actually performs the work is from an event of a class, it has no knowledge of the BackgrounWorker :-(
schmoopy
+1  A: 

As far as I know the best you could probably get away with using a background worker is (assuming the constrants you've mentioned so far):

private void SetupThread()
{
    BackgroundWorker bw = new BackgroundWorker();
    // Assuming you need sender and e. If not, you can just send bw
    bw.DoWork += new DoWorkEventHandler(DoTheWork);
}

private void DoTheWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    MyClass.Callback = () => 
        {
            ((BackgroundWorker)bw).UpdateProgress(/*send your update here*/);
            MethodCalledFromEventCallback();
        };

    MyClass.DoSomething(); // This will produce a callback(event) from MyClass
}

private void MethodCalledFromEventCallback() 
{ 
    // You've already sent an update by this point, so no background parameter required
}
Gordon Tucker
A: 

Your design requirements need a bit of work. A method that must use BackgroundWorker.UpdateProgress can't take the BackgroundWorker as a parameter? You could modify Gordon's answer to take a delegate instead, I suppose.

If you want this kind of separation of concerns, then you'll probably be a lot happier using the Task library in 4.0. They separate the work to be done (the "update" code) from the scheduling of that work.

Stephen Cleary