gpt4 book ai didi

c# - C# 中的命令模式和异步操作处理

转载 作者:太空狗 更新时间:2023-10-30 01:08:41 26 4
gpt4 key购买 nike

我想听听有关使用命令模式处理异步操作的最佳方式的意见。假设我们有以下示例:

public class MyCommand 
{
// Sets up receiver and does whatever stuff

public void Execute()
{
_myReceiver.DoSomething();
}
}

问题是:MyCommand 不知道 MyReceiver.DoSomething() 是否有代码的异步部分。如果我想在 MyCommand 执行后将其压入撤消堆栈,我无法保证其接收器操作已完全执行,从而无法确定 MyCommand 是否达到可以撤消的状态。

我个人想到了以下解决方案:

  1. 在 Command 中实现某种状态控制
  2. 在命令中包含“BeginExecute”和“EndExecute”
  3. 在 MyReceiver 中包含事件并让 Command 订阅它们(我觉得这很臭)

总结一下,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
}

我现在有办法确保命令的接收器已完成执行任何操作,并且已准备好将其插入撤消堆栈。但是,要向每个包含异步操作的 Receiver 类发送垃圾邮件确实让我很烦恼。

我在 Internet 上没有找到太多关于这个主题的信息,很想听听不同的方法。

OBS:让命令管理所有与异步相关的代码不是一个选项:)。

最佳答案

我认为您在一节课上发生的事情太多了。我会这样分解它:

// An immutable command, to be handled in-process.  
// ICommand is a marker interface with no members.
public class DoSomething : ICommand
{
public readonly Id;

public DoSomething(Guid id)
{
Id = id;
}
}

// To be handled out-of-process.
[AsynchronousCommand]
public class DoSomethingThatTakesAReallyLongTime : ICommand
{
public readonly Id;

public DoSomethingThatTakesAReallyLongTime(Guid id)
{
Id = id;
}
}

// This guy could take any number of dependencies: ISomethingRepository, DbContext, etc.
// Doesn't matter, but it's probably gonna have dependencies.
public class DoSomethingHandler : IHandler<DoSomething>
{
public void Handle(DoSomething command) // IHandler<T>'s only member
{
// CRUD or call call a domain method
}
}

public class CommandService : ICommandService
{
public void Execute(params ICommand[] commands) // ICommandService's only member
{
foreach(var command in commands)
{
var handler = GetHandler(command); // Could use your IOC container.

if (HasAsyncAttribute())
new Action(() => handler.Handle(command)).BeginInvoke(null, null);
else
handler.Handle(command);
}
}
}

// Something that might consume these
public class SomethingController
{
private readonly ICommandService _commandService;

public SomethingController(ICommandService commandService)
{
_commandService = commandService;
}

[HttpPost]
public void DoSomething(Guid id)
{
_commandService.Execute(new DoSomething(id));
}

[HttpPost]
public void DoSomethingThatTakesAReallyLongTime(Guid id)
{
_commandService.Execute(new DoSomethingThatTakesAReallyLongTime(id));
}
}

这里的最大优势是您可以将命令分发给客户端,而无需显式拖动处理程序附带的所有依赖项。客户端不应知道处理程序。客户端只需要知道它发送了一个命令,并且所有命令都应该被假定为成功。

关于c# - C# 中的命令模式和异步操作处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8749951/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com