Say I have 4 classes
- ControllerClass
- MethodClass1
- MethodClass2
- MethodClass3
and each MethodClass has an asynchronous method DoStuff() and each has a CompletedEvent.
The ControllerClass is responsible for invoking the 3 asynchronous methods on the 3 MethodClasses in a particular order.
So ControllerClass invokes MethodClass1.DoStuff() and subscribes to MethodClass1.CompletedEvent. When that event is fired, ControllerClass invokes MethodClass2.DoStuff() and subscribes to MethodClass2.CompletedEvent. When that event is fired, the ControllerClass invokes MethodClass3.DoStuff()
Is there a best practice for a situation like this? Is this bad design?
I believe it is because
- I am finding it hard to unit test (a sure sign)
- It is not easy to change the order
- I have an uneasy, code-smell feeling about it
What are the alternatives in a situation like this?
Note: I am 开发者_JS百科targeting the .NET 2.0 framework
Jeff Richter has a great article about using enumerators to simplify APM code. Microsoft CCR also uses a similar technique. Worth investigating:
http://msdn.microsoft.com/en-us/magazine/cc546608.aspx
If you have access to the code of the classes that you are invoking, and also have the freedom to change it, why not wrap it up in a handler (implementing Chain of Responsibility pattern). You can then define successor for each method. That will keep the complexity low with a higher flexibility.
What version of .NET are we using? In .NET 4.0 there is the Task class which you can use to fire tasks, and change the order very easily.
A good example is here: http://blogs.msdn.com/pfxteam/
You can see how you can queue up tasks.
There's no point in doing it this way. Call one helper method asynchronously. It should call the three methods you are now running asynchronously. Sequencing them is now simple and you only have one async method to worry about. More efficient too, you are not starting and switching between threads anymore. It actually takes less time.
Since the three methods you are using needed to be run in a particular order and they need to wait for each other, why do you bother calling them asynchronously? Just make simple synchronous calls.
精彩评论