fer*_*ero 5 c# design-patterns asynchronous
我想听听有关使用Command模式处理异步操作的最佳方法的意见。假设我们有以下示例:
public class MyCommand
{
// Sets up receiver and does whatever stuff
public void Execute()
{
_myReceiver.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是:MyCommand不知道MyReceiver.DoSomething()是否具有代码的异步部分。如果我想在MyCommand执行之后将MyCommand推入撤消堆栈,则无法保证其接收者动作已完全执行,因此不确定MyCommand是否已达到可以撤消的状态。
我个人认为以下解决方案:
总结一下,MyCommand会变成:
public class MyCommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
_myReceiver.DoSomethingFinished += () => this.EndExecute();
}
public void BeginExecute()
{
this.EnterExecutionState();
_myReceiver.DoSomething();
}
public void EndExecute()
{
this.LeaveExecutionState();
}
// State handling related stuff
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以确保命令的接收方已经完成了任何操作,并准备将其推入撤消堆栈。但是,对于事件垃圾邮件,每一个包含异步操作的Receiver类的确给我带来了麻烦。
我在Internet上没有找到太多有关此主题的信息,很想听听其他方法。
OBS:不能使命令管理所有与异步相关的代码:)。
像这样的东西吗?
public interface ICommand
{
void Execute();
event EventHandler Finished;
}
public class MyCommand : ICommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
_myReceiver.DoSomethingFinished += () => Finished(); // dont forget null check here.
}
public void Execute()
{
_myReceiver.DoSomething();
}
public event EventHandler Finished;
}
Run Code Online (Sandbox Code Playgroud)
这样,该命令的用户可以注册到 Finished 事件,以便知道命令何时完成其异步行为并可以采取相应的操作。
或者如果你不想使用事件,那么回调呢?
public class MyCommand : ICommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
}
public void Execute()
{
_myReceiver.DoSomething(() => Finished()); // dont forget null check here.
}
public event EventHandler Finished;
}
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,MyReciever 只需要有一种方法来通知其调用者它已完成。没有办法绕过它。