Abstraction of a pattern noticed involving BackgroundWorker
I am noticing a pattern like below in few of my classes. How can I abstract that away? Any suggestions?
private void InitializeClass()
{
BackgroundWorker bgw1 = new BackgroundWorker();
bgw1.DoWork += (s,e) =>
{
// doing wo开发者_开发知识库rk
};
BackgroundWorker bgw2 = new BackgroundWorker();
bgw2.DoWork += (s,e) =>
{
// doing work
};
BackgroundWorker bgw3 = new BackgroundWorker();
bgw3.DoWork += (s,e) =>
{
// doing work
};
bgw1.RunWorkerAsync();
bgw2.RunWorkerAsync();
bgw3.RunWorkerAsync();
}
public static class Worker
{
public static void Execute(params DoWorkEventHandler[] handlers)
{
foreach (DoWorkEventHandler handler in handlers)
{
BackgroundWorker worker = new BackgroundWorker();
DoWorkEventHandler capturedHandler = handler;
worker.DoWork += (sender, e) =>
{
try
{
capturedHandler(sender, e);
}
finally
{
worker.Dispose();
}
};
worker.RunWorkerAsync();
}
}
}
and then:
Worker.Execute((s, e) =>
{
// doing work
});
or if you wanted to schedule multiple events:
Worker.Execute(
(s, e) =>
{
// doing work
},
(s, e) =>
{
// doing work
},
(s, e) =>
{
// doing work
}
);
UPDATE:
Here's an alternative which allows you to specify a completed handler:
public class Worker
{
public Worker Work(DoWorkEventHandler doWork, RunWorkerCompletedEventHandler complete)
{
var worker = new BackgroundWorker();
worker.DoWork += doWork;
worker.RunWorkerCompleted += complete;
worker.RunWorkerAsync();
return this;
}
}
and then:
new Worker()
.Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ })
.Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ })
.Work((s, e) => { /** some work **/ }, (s, e) => { /** work completed **/ });
May be you can do something like this. A pseudocode:
public abstract class BaseClass
{
public abstract DoWork1();
public abstract DoWork2();
public abstract DoWork3();
protected void InitializeClass()
{
BackgroundWorker bgw1 = new BackgroundWorker();
bgw1.DoWork += (s,e) =>
{
DoWork1();
};
BackgroundWorker bgw2 = new BackgroundWorker();
bgw2.DoWork += (s,e) =>
{
DoWork2();
};
BackgroundWorker bgw3 = new BackgroundWorker();
bgw3.DoWork += (s,e) =>
{
DoWork3();
};
bgw1.RunWorkerAsync();
bgw2.RunWorkerAsync();
bgw3.RunWorkerAsync();
}
}
after this in any derived class, something like this:
public class DerivedClass: BaseClass
{
public override DoWork1(){} //DoWork1 concrete implementaiton
public override DoWork2(){} //DoWork2 concrete implementaiton
public override DoWork3(){} //DoWork3 concrete implementaiton
}
So when you call InitializeClass()
method, you call base class method which will invoke overrides of concrete class.
Remark: If the number of background workers can vary, you can merge a solution of Darin with this one (in other words have a collection of invokers).
Hope this helps.
精彩评论