Я не уверен, что лучше всего подходит для передачи событий по линии родительским классам и нуждается в некоторой обратной связи.Как пересылать асинхронные события родительским классам?
Приведенный ниже примерный пример иллюстрирует то, что я хочу достичь.
namespace test {
public delegate void TestCompletedEventHandler(object sender,
TestCompletedEventArgs e);
public class Manager {
CarList m_carlist = null;
public CarList Cars {
get { return m_carlist; }
set { m_carlist = value; }
}
public Manager() {
Cars = new CarList(this);
}
public void Report(bool successfull) {
//...
}
}
public class CarList : List<Car> {
protected internal event TestCompletedEventHandler
Car_TestCompleted = null;
protected readonly Manager m_manager = null;
public Manager Manager {
get { return m_manager; }
}
public CarList(Manager manager) {
m_manager = manager;
}
public void Test() {
foreach(Car car in this) {
bool ret = car.Test();
manager.Report(ret);
}
}
public void Add(Car car) {
//Is this a good approach?
car.TestCompleted +=
new TestCompletedEventHandler(Car_TestCompleted_Method);
base.Add(car);
}
private void Car_TestCompleted_Method(object sender,
TestCompletedEventArgs e)
{
if(Car_TestCompleted != null) Car_TestCompleted(sender, e);
}
}
public class Car {
protected internal event TestCompletedEventHandler
TestCompleted = null;
public bool Test() {
//...
if(TestCompleted != null) TestCompleted(this,
new TestCompletedEventArgs())
}
}
public class TestCompletedEventArgs : EventArgs {
//...
}
}
using test;
Manager manager = new Manager();
manager.Cars.Car_TestCompleted +=
new TestCompletedEventHandler (Car_TestCompleted_Method);
manager.Cars.Test();
Еще более конкретный пример:
//Contains DataItems and interfaces for working with them
class DataList
{
public List<DataItem> m_dataitems { get; set; }
public TestManager m_testmanager { get; set; }
// ...
}
class DataItem
{
// ...
}
//A manager class for running tests on a DataList
class TestManager
{
public List<TestSource> m_sources { get; set; }
public WorkerManager m_workermanager { get; set; }
// ...
}
//A common interface for Tests
abstract class TestSource
{
public event EventHandler<EventArgs<object>> Completed = null;
protected TestManager m_owner { get; set; }
public abstract void RunAsync();
// ...
}
//A test
class Test1 : TestSource
{
public virtual void RunAsync()
{
//Add commands
//Run workers
//Report progress to DataList and other listeners (like UI)
//Events seem like a bad approach since they need to be forwarded through many levels of abstraction
if(Completed != null) Completed(this, new EventArgs<object>(null));
}
// ...
}
//Manages a number of workers and a queue of commands
class WorkerManager
{
public List<MyWorker> m_workers { get; set; }
public Queue<Command> m_commands { get; set; }
}
//Wrapper for BackgroundWorker
class MyWorker
{
// ...
}
//Async command
interface Command
{
// ...
}
Не хотите ли вы передать их ** вверх ** родителям? ;) –