c# – 我如何处理异步任务我不想等待?
我正在写一个多玩家游戏服务器,并正在寻找新的C#异步/等待功能的方法
帮我.服务器的核心是更新游戏中所有角色的循环 能够: while (!shutdown) { foreach (var actor in actors) actor.Update(); // Send and receive pending network messages // Various other system maintenance } 需要这个循环来处理数千个演员,并且每秒钟更新多次以保持 由于这是一个控制台应用程序,我打算写一个可以发送的SynchronizationContext Thing foo; public override void Update() { foo.DoThings(); if (someCondition) { UpdateAsync(); } } async void UpdateAsync() { // Get data,but let the server continue in the mean time var newFoo = await GetFooFromDatabase(); // Now back on the main thread,update game state this.foo = newFoo; } 我可以使Update()异步并将任务传播回主循环,但是: >我不想增加数千个永远不会使用它的更新的开销. 我不能等待的所有这些任务怎么办?唯一的时候,我可能想知道他们所有 解决方法
我的理解是,它的关键是你想要的:
while (!shutdown) { //This should happen immediately and completions occur on the main thread. foreach (var actor in actors) actor.Update(); //includes i/o bound database operations // The subsequent code should not be delayed ... } while循环在主控制台线程中运行的位置.这是一个紧密的单线程循环.您可以并行运行foreach,但是您仍然会等待最长的运行实例(i / o绑定操作从数据库获取数据). 等待异步不是此循环中的最佳选项,您需要在线程池上运行这些i / o数据库任务.在线程池异步等待将释放池线程是有用的. 所以,下一个问题是如何将这些完成回到主线程.嗯,好像你需要一些相当于主线程上的消息泵的东西.有关如何做到这一点的信息,请参阅this post,尽管这可能有点沉重.您可以在每次通过while循环时,在主线程上检查完成队列.您将使用concurrent data structures之一来做到这一点,所有这些都是线程安全的,然后设置Foo如果需要设置. 似乎有一些空间来合理化这个投票的演员和线程,但是不知道应用程序的细节是很难说的. 几点: – >如果您没有等待更高的任务,您的主控制台线程将退出,您的应用程序也将退出.详见here. 对于火而忘记,您可以根据您的方案使用以下选项之一: >使用Task.Run或Task.StartNew.见here for differences. 请注意以下事项: – >您将需要处理您生成的任务/线程中的异常.如果您没有观察到任何异常,您可能需要处理这些异常,即使只是记录其发生.请参阅unobserved exceptions上的信息. 如果您想了解这些任务的状态,那么您将需要以某种方式跟踪它们,无论是内存列表还是通过查询自己的线程池的队列或通过查询持久性机制进行查询.关于持久性机制的好处是,它对崩溃是有弹性的,在关机期间,您可以立即关闭,然后在重新启动的时候选择你最后的位置(这当然取决于任务运行的重要程度一段时间内). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |