我正在尝试使用C#的新await
功能实现NPC脚本。 This is my proof of concept.
在NPC.cs
中,您可以看到以下代码段:
public async void Run(INPC npc)
{
npc.Say("Hello!");
await npc.WaitForOk();
npc.Say("This is an example of some weird crap.");
await npc.WaitForOk();
npc.Say("Bye.");
await npc.WaitForOk();
}
在一个真实的例子中,脚本将以IronPython等脚本语言实现。即使它将来可能支持async
/ await
关键字,但每次通话都必须这样做是非常麻烦和恼人的。
我尝试过另一种方法是异步并进行等待,让脚本只是调用它,但由于async
/ await
的工作方式,脚本方法({{1只会继续而不会暂停/阻止。
有没有办法避免必须使脚本方法异步并且必须在每次调用前使用Run
,同时仍然保留类似协程的功能?
此外,如果有一个更好的解决方案已经可用,而不是使用await
/ async
同时仍然保持线程效率,请突出显示它。
谢谢!
答案 0 :(得分:1)
对于async
/ await
来说,这是一个非常有趣的用途。
我已经将很多与语法相关的问题从网络编译成one of my blog posts。简而言之,有充分理由说明async
和await
都是必需的。
如果您愿意向NPC添加状态,请考虑使用基于观察者的方法(Rx)。这种方法能够进行复杂的交互,也可以允许并行执行不同的NPC。
您还可以在线程池任务上模拟NPC,这非常有效 - 当它们阻塞时,CPU可用于其他任务。
答案 1 :(得分:1)
我不确定你为什么要这么努力避免await
。我认为对这种代码要求它是一个好主意,因为很难说出代码实际上做了什么。所以,我认为以这种方式使用await
可能是你最好的选择。
另外,如果可以的话,最好避免使用async void
方法,因为你无法捕获它们抛出的异常。
我可以想象有办法避免写async
,例如:
npc.AddAction(n => n.Say("Hello!"))
.AddAction(n => n.WaitForOk())
.AddAction(n => n.Say("This is an example of some weird crap."))
.AddAction(n => n.WaitForOk());
npc.Run();
此处,Run()
处理使用AddAction()
构建的操作列表,并在必要时使用await
。
但我怀疑你能否像使用await
s那样简单。 (另外,在这样的代码中实现任何类型的控制流都会使它真的难以理解。)