如何用C#将委托排队在后台串行执行?

2023-12-03

从游戏循环中,我想在后台开始工作,该工作应该一个接一个地执行,但不应阻止游戏循环。

所以理想情况下是一个类BackgroundQueue可以这样使用:

BackgroundQueue myQueue = new BackgroundQueue();
//game loop called 60 times per second
void Update()
{
    if (somethingHappens)
    {
        myQueue.Enqueue(() => MethodThatTakesLong(someArguments))
    }   
}

.NET 中是否有适合该场景的现成类?或者有人知道如何实施的一个很好的例子BackgroundQueue class?

如果类可以报告它当前是否正在做某事以及有多少代表在排队,那就太好了......


一种解决方案来自优秀的C# 中的线程电子书。在关于基本结构的部分中,作者几乎完全符合您的要求在一个例子中.

点击该链接并向下滚动到生产者/消费者队列。

在后面的部分中,他谈到了这一点并发队列也可以很好地工作,除了高并发场景之外,它在所有情况下都表现较差。但对于低负载的情况,让某些东西轻松工作可能会更好。我对文档中的声明没有个人经验,但它可供您评估。

我希望这有帮助。

Edit2:根据 Evk 的建议(谢谢!),阻塞收集类看起来像你想要的。默认情况下,它在底层使用 ConcurrentQueue。我特别喜欢完成添加方法,以及使用 CancellationTokens 的能力。当事情发生阻塞时,“关闭”场景并不总是被正确考虑,但在我看来,这是正确的。

编辑 3:根据要求,提供了如何与 BlockingCollection 一起使用的示例。我用的是foreach and GetConsumingEnumerable为了让消费者方面的问题变得更加紧凑:

using System.Collections.Concurrent;
private static void testMethod()
{
  BlockingCollection<Action> myActionQueue = new BlockingCollection<Action>();
  var consumer = Task.Run(() =>
  {
    foreach(var item in myActionQueue.GetConsumingEnumerable())
    {
      item(); // Run the task
    }// Exits when the BlockingCollection is marked for no more actions
  });

  // Add some tasks
  for(int i = 0; i < 10; ++i)
  {
    int captured = i; // Imporant to copy this value or else
    myActionQueue.Add(() =>
    {
      Console.WriteLine("Action number " + captured + " executing.");
      Thread.Sleep(100);  // Busy work
      Console.WriteLine("Completed.");
    });
    Console.WriteLine("Added job number " + i);
    Thread.Sleep(50);
  }
  myActionQueue.CompleteAdding();
  Console.WriteLine("Completed adding tasks.  Waiting for consumer completion");

  consumer.Wait();  // Waits for consumer to finish
  Console.WriteLine("All actions completed.");
}

我添加了 Sleep() 调用,以便您可以看到在消耗其他内容时添加了内容。您还可以选择启动任意数量的consumerlambda(简称为Action,然后启动Action多次)或加法循环。并且您可以随时致电Count在集合上获取未运行的任务数。据推测,如果该值不为零,则您的生产者任务正在运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何用C#将委托排队在后台串行执行? 的相关文章

随机推荐

  • getLastRow() 的问题

    我对 getLastRow 有疑问 我认为这个函数应该返回包含数据的最后一行 但是 由于我正在处理的工作表在填充数据的行下方有更多的空行 因此这些函数似乎会进入并选择执行时的最后一个空行 而不是选择包含数据的最后一行 这可能不会是相同的 有
  • 模板中的 for 循环

    I need for在模板中循环 for i start i lt finish i do something 这只是使用的一种方式吗range使用准备好的数组或者如何将此功能添加到模板中 最简单的方法可能是使用range和一个外部函数 例
  • iOS WKWebview loadHTMLString(_ baseURL:) 加载图像和读取css失败

    我知道这个问题以前曾被问过 但我的情况有些不同 我正在尝试打电话给loadHTMLString baseURL on WKWebview我的 baseURL 位于AppData Documents目录 我需要HTMLstring加载并且需要
  • 数据流失败并出现 java.lang.NoSuchMethodError: io.grpc.protobuf.ProtoUtils.marshaller(Lcom/google/protobuf/Message;)

    我正在尝试让 Dataflow 作业在 Google Cloud 上运行 它总是失败 java lang NoSuchMethodError io grpc protobuf ProtoUtils marshaller Lcom googl
  • 在打字稿中,有没有办法确保函数的返回类型是详尽的?

    如果你有一个像这样的常量枚举 enum Color RED GREEN BLUE 您可以编写一个助手和一个 switch 语句 function assertNever x never never throw new Error Unexp
  • 在 Python 中使用 BeautifulSoup 识别和替换 XML 元素

    我正在尝试使用 BeautifulSoup4 来查找和替换 XML 中的特定元素 更具体地说 我想找到 file name 的所有实例 在下面的示例中 文件名是 Cyp26A1 atRA minus tet plus txt 并将其替换为该
  • 如何在 Visual Studio 中向解决方案资源管理器添加自定义图标

    我正在尝试将自定义图标添加到 Visual Studio 中的解决方案资源管理器 就像文件图标扩展 does 我认为我已经为 Visual Studio 做了所有正确的事情 将新图标与以 结尾的文件关联起来 d and di扩展 但 Vis
  • 如何创建具有运行时间限制的数据结构

    我需要实现一个支持插入删除和搜索的数据结构 O log n 并在 O 1 中提取特殊对象 我的数据结构需要保存按 ID 排序的车辆 并且每辆车都有一个字段表示距离下一次服务的时间 我需要在 O 1 时间内提取接下来需要提供服务的车辆 欢迎所
  • 如何在Protege 4.3.0中启用Pellet?

    已经过去快一年了无法下载 Protege 4 3 的 Pellet 插件建议该版本不可用 有什么改变吗 应该可以从他们的 github 下载它并将其放入 Prog g 的插件文件夹中 https github com Complexible
  • 重复时间序列数据的 Pandas 滚动中位数

    我看到 Pandas 不允许重复的时间序列索引 yet https github com pydata pandas issues 643 但很快就会添加 我想知道是否有一种好方法可以通过多索引标签 列将滚动窗口方法应用于具有重复时间的数据
  • parseInt() 和 parseFloat() 位于哪里?

    当我在控制台中按 TAB 时 我看到了 parseInt 和 parseFloat 我只需输入 parseInt 123asd 但这些位于哪里 它们是全局对象的属性 内置函数 对于浏览器来说 这是window
  • 字符串作为数组索引

    In 3 XoePhoenix 数组索引是字符数组类型 我们可以用 C 来做这个吗 数组索引不是必须是整数吗 什么是3 XeoPhoenix mean 3 XoePhoenix 是相同的 XoePhoenix 3 所以它将评估为 char
  • IE10、11 带连字符的 CDATA 解析错误

    我遇到过这样的问题 当尝试解析从服务器收到的 xml 时 CDATA 块中包含的消息在 IE10 11 中解析 直到找到第一个连字符 请参阅我收到的 XML 示例
  • Chrome headless 忽略系统代理

    编辑 这是演示该问题的 YouTube 视频 https youtu be MIZjHKCVr1s 我正在使用 headless 标志与 chrome 一起运行 selenium 但显然使用 headless 似乎会忽略系统代理 我之前在
  • 将数组中的对象推入循环内[重复]

    这个问题在这里已经有答案了 几个小时以来 我一直在尝试解决这个问题 但我似乎确实无法成功 我正在尝试创建一个 JSON 字符串 如下所示 但是在传递变量的值时obj到变量j我得到的数组仅包含该循环的最后一个结果 而不是得到如下结果 mach
  • SCI - 系统控制中断向量是如何定义的?

    根据 ACPI 规范 FADT 固定 ACPI 描述表 表包含一个字段 用于报告SCI中断操作系统的编号 该字段定义如下 我在 Intel x86 平台上转储了 FADT 表 看到 SCI 中断与编号相关联9 但根据英特尔手册 0 31是
  • matplotlib 动态子图数量

    我正在尝试使用以下方法获取子图matplotlib 数量为subplots在运行时计算 如pnum以下示例有所不同 pnum len args m f ax1 ax2 plt subplots pnum sharex True sharey
  • 从 iOS 导出椭圆曲线密钥以与 OpenSSL 配合使用

    我生成了私钥 公钥对并将其存储在 Secure Enclave 内 它是 256 位椭圆曲线密钥 唯一可以存储在 Secure Enclave 中的密钥类型 I use SecKeyCreateWithData and SecKeyCopy
  • 使用主机 SSH 密钥在 DockerFile 中访问私有 Git 存储库

    我是 Docker 新手 正在尝试让我的 Angular Web 应用程序在容器中构建和运行 我在项目的根目录中有一个非常基本的 Dockerfile 如下所示 Create the image based on the official
  • 如何用C#将委托排队在后台串行执行?

    从游戏循环中 我想在后台开始工作 该工作应该一个接一个地执行 但不应阻止游戏循环 所以理想情况下是一个类BackgroundQueue可以这样使用 BackgroundQueue myQueue new BackgroundQueue ga