C# 并发控制框架之单线程环境下实现每秒百万级调度

 更新时间:2024年10月17日 09:46:53   作者:小码编匠  
本文介绍了一款专为工业自动化及机器视觉开发的C#并发流程控制框架,通过模仿Go语言并发模式设计,支持高频调度及复杂任务处理,已在多个项目中验证其稳定性和可靠性

前言

在工业自动化和机器视觉领域,对实时性、可靠性和效率的要求越来越高。为了满足这些需求,我们开发了一款专为工业自动化运动控制和机器视觉流程开发设计的 C# 并发流程控制框架。

该框架不仅适用于各种工业自动化场景,还能在单线程环境下实现每秒百万次以上的调度频率,从而从容应对涉及成千上万输入输出点数的复杂任务。

并发流程控制框架

本框架提供一种全新的并发流程控制框架,它借鉴了Golang语言中的高效并发模式,并在此基础上进行了必要的功能扩展。框架不仅能够支持自定义的单/多线程调度机制,还允许在主UI线程中进行调度,从而简化了逻辑与用户界面之间的交互。

另外,该框架还集成了高精度定时器、可配置的调度优先级、逻辑停止与暂停等功能,让我们能够更加灵活地管理和控制复杂的自动化流程。

框架优势

  • 相较于传统模型:相对于传统的多线程模型、状态机模型以及类PLC模型,本框架具有更加紧凑清晰的逻辑结构,显著提升了开发效率,并简化了后续的维护与升级过程。
  • 受Go语言启发:框架的设计借鉴了 Go 语言中的高效并发模式,并在此基础上进行了必要的功能扩展,以适应工业自动化领域的具体需求。
  • 灵活的调度机制:支持自定义单线程或多线程调度,同时也可在主 UI 线程中进行调度,便于逻辑与用户界面的交互,增强了用户体验。
  • 丰富的内置功能:内置高精度定时器、可配置的调度优先级、逻辑停止与逻辑暂停功能,确保任务执行的准确性和可控性。
  • 树形多任务调度:采用树形结构管理多任务调度,提高了逻辑的可靠性和系统的整体稳定性。
  • 卓越的性能表现:在单线程环境下,每秒可实现超过一百万次的调度频率,能够从容应对成千上万输入输出点数的复杂场景。
  • 广泛的实践验证:该框架已在多个实际项目中成功应用,证明了其稳定性和可靠性。

框架示例

代码中定义了一系列不同的任务执行模式,展示如何通过不同的调度策略来管理并发任务。

  • 全局变量

static shared_strand strand:全局共享的调度器,用于保证线程安全。

  • 日志记录函数

Log(string msg):记录带有时间戳的日志信息到控制台。

  • 工作任务函数

Worker(string name, int time = 1000):模拟一个简单的任务,该任务会在指定的毫秒数后打印一条消息。

  • 主函数

MainWorker():异步主任务函数,依次调用前面定义的各种任务模式。

Main(string[] args):程序入口点,初始化工作服务、共享调度器,并启动主任务。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Go;
namespace WorkerFlow
{
    class Program
    {
        static shared_strand strand;
        static void Log(string msg)
        {
            Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} {msg}");
        }
        static async Task Worker(string name, int time = 1000)
        {
            await generator.sleep(time);
            Log(name);
        }
        //1 A、B、C依次串行
        //A->B->C
        static async Task Worker1()
        {
            await Worker("A");
            await Worker("B");
            await Worker("C");
        }
        //2 A、B、C全部并行,且依赖同一个strand(隐含参数,所有依赖同一个strand的任务都是线程安全的)
        //A
        //B
        //C
        static async Task Worker2()
        {
            generator.children children = new generator.children();
            children.go(() => Worker("A"));
            children.go(() => Worker("B"));
            children.go(() => Worker("C"));
            await children.wait_all();
        }
        //3 A执行完后,B、C再并行
        //  -->B
        //  |
        //A->
        //  |
        //  -->C
        static async Task Worker3()
        {
            await Worker("A");
            generator.children children = new generator.children();
            children.go(() => Worker("B"));
            children.go(() => Worker("C"));
            await children.wait_all();
        }
        //4 B、C都并行执行完后,再执行A
        //B--
        //  |
        //  -->A
        //  |
        //C--
        static async Task Worker4()
        {
            generator.children children = new generator.children();
            children.go(() => Worker("B"));
            children.go(() => Worker("C"));
            await children.wait_all();
            await Worker("A");
        }
        //5 B、C任意一个执行完后,再执行A
        //B--
        //  |
        //  >-->A
        //  |
        //C--
        static async Task Worker5()
        {
            generator.children children = new generator.children();
            var B = children.tgo(() => Worker("B", 1000));
            var C = children.tgo(() => Worker("C", 2000));
            var task = await children.wait_any();
            if (task == B)
            {
                Log("B成功");
            }
            else
            {
                Log("C成功");
            }
            await Worker("A");
        }
        //6 等待一个特定任务
        static async Task Worker6()
        {
            generator.children children = new generator.children();
            var A = children.tgo(() => Worker("A"));
            var B = children.tgo(() => Worker("B"));
            await children.wait(A);
        }
        //7 超时等待一个特定任务,然后中止所有任务
        static async Task Worker7()
        {
            generator.children children = new generator.children();
            var A = children.tgo(() => Worker("A", 1000));
            var B = children.tgo(() => Worker("B", 2000));
            if (await children.timed_wait(1500, A))
            {
                Log("成功");
            }
            else
            {
                Log("超时");
            }
            await children.stop();
        }
        //8 超时等待一组任务,然后中止所有任务
        static async Task Worker8()
        {
            generator.children children = new generator.children();
            children.go(() => Worker("A", 1000));
            children.go(() => Worker("B", 2000));
            var tasks = await children.timed_wait_all(1500);
            await children.stop();
            Log($"成功{tasks.Count}个");
        }
        //9 超时等待一组任务,然后中止所有任务,且在中止任务中就地善后处理
        static async Task Worker9()
        {
            generator.children children = new generator.children();
            children.go(() => Worker("A", 1000));
            children.go(async delegate ()
            {
                try
                {
                    await Worker("B", 2000);
                }
                catch (generator.stop_exception)
                {
                    Log("B被中止");
                    await generator.sleep(500);
                    throw;
                }
                catch (System.Exception)
                {
                }
            });
            var task = await children.timed_wait_all(1500);
            await children.stop();
            Log($"成功{task.Count}个");
        }
        //10 嵌套任务
        static async Task Worker10()
        {
            generator.children children = new generator.children();
            children.go(async delegate ()
            {
                generator.children children1 = new generator.children();
                children1.go(() => Worker("A"));
                children1.go(() => Worker("B"));
                await children1.wait_all();
            });
            children.go(async delegate ()
            {
                generator.children children1 = new generator.children();
                children1.go(() => Worker("C"));
                children1.go(() => Worker("D"));
                await children1.wait_all();
            });
            await children.wait_all();
        }
        //11 嵌套中止
        static async Task Worker11()
        {
            generator.children children = new generator.children();
            children.go(() => Worker("A", 1000));
            children.go(async delegate ()
            {
                try
                {
                    generator.children children1 = new generator.children();
                    children1.go(async delegate ()
                    {
                        try
                        {
                            await Worker("B", 2000);
                        }
                        catch (generator.stop_exception)
                        {
                            Log("B被中止1");
                            await generator.sleep(500);
                            throw;
                        }
                        catch (System.Exception)
                        {
                        }
                    });
                    await children1.wait_all();
                }
                catch (generator.stop_exception)
                {
                    Log("B被中止2");
                    throw;
                }
                catch (System.Exception)
                {
                }
            });
            await generator.sleep(1500);
            await children.stop();
        }
        //12 并行执行且等待一组耗时算法
        static async Task Worker12()
        {
            wait_group wg = new wait_group();
            for (int i = 0; i < 2; i++)
            {
                wg.add();
                int idx = i;
                var _ = Task.Run(delegate ()
                {
                    try
                    {
                        Log($"执行算法{idx}");
                    }
                    finally
                    {
                        wg.done();
                    }
                });
            }
            await wg.wait();
            Log("执行算法完成");
        }
        //13 串行执行耗时算法,耗时算法必需放在线程池中执行,否则依赖同一个strand的调度将不能及时
        static async Task Worker13()
        {
            for (int i = 0; i < 2; i++)
            {
                await generator.send_task(() => Log($"执行算法{i}"));
            }
        }
        static async Task MainWorker()
        {
            await Worker1();
            await Worker2();
            await Worker3();
            await Worker4();
            await Worker5();
            await Worker6();
            await Worker7();
            await Worker8();
            await Worker9();
            await Worker10();
            await Worker11();
            await Worker12();
            await Worker13();
        }
        static void Main(string[] args)
        {
            work_service work = new work_service();
            strand = new work_strand(work);
            generator.go(strand, MainWorker);
            work.run();
            Console.ReadKey();
        }
    }
}

框架地址

总结

值得一提的是,该框架特别设计用于工业自动化运动控制以及机器视觉流程开发领域,其独特的树形多任务调度机制极大提高了逻辑的可靠性,同时单线程环境下的每秒调度次数可达一百万次以上,足以应对涉及成千上万输入输出点数的应用场景。经过多个项目的实际验证,证明了其稳定性和可靠性,为工业自动化提供了强有力的支持。

通过本文的介绍,希望能为工业自动化领域的开发者提供一个高效、可靠且易于使用的工具。借助这一工具,大家在构建复杂的控制系统时,能够更加轻松地应对并发处理的挑战。也期待您在评论区留言交流,分享您的宝贵经验和建议。

到此这篇关于C# 并发控制框架之单线程环境下实现每秒百万级调度的文章就介绍到这了,更多相关C# 每秒百万级调度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#实现异步的常用方式总结

    C#实现异步的常用方式总结

    这篇文章主要为大家详细介绍了C#实现异步的几个常用方式,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
    2023-05-05
  • C# Datatable筛选过滤的四种方法实现

    C# Datatable筛选过滤的四种方法实现

    本文主要介绍了C# Datatable筛选过滤的四种方法实现,包括Select、LINQ、DataView、动态条件,各方法在排序、性能及适用场景上有不同特点,感兴趣的可以了解一下
    2025-06-06
  • C#操作config文件的具体方法

    C#操作config文件的具体方法

    这篇文章介绍了在C#中对config文件的操作,有需要的朋友可以参考一下
    2013-07-07
  • C#使用dynamic类型访问JObject对象

    C#使用dynamic类型访问JObject对象

    这篇文章主要为大家详细介绍了C#使用dynamic类型访问JObject对象,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • C#实现在listview中插入图片实例代码

    C#实现在listview中插入图片实例代码

    这篇文章主要介绍了C#实现在listview中插入图片实例代码的相关资料,需要的朋友可以参考下
    2017-03-03
  • C#正则表达式的详细使用说明(附示例代码)

    C#正则表达式的详细使用说明(附示例代码)

    正则表达式是一种匹配输入文本的模式,Net框架提供了允许这种匹配的正则表达式引擎,模式由一个或多个字符、运算符和结构组成,这篇文章主要介绍了C#正则表达式的详细使用说明,需要的朋友可以参考下
    2025-07-07
  • C#定时器与延时操作的使用

    C#定时器与延时操作的使用

    本文详细介绍了C#开发中常用的定时器与延时机制,主要内容包括 定时器类对比,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-04-04
  • Unity3D基于UGUI实现虚拟摇杆

    Unity3D基于UGUI实现虚拟摇杆

    这篇文章主要为大家详细介绍了Unity3D基于UGUI实现虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#实现PDF文件添加图片背景

    C#实现PDF文件添加图片背景

    这篇文章主要介绍了C#实现PDF文件添加图片背景的相关资料,需要的朋友可以参考下
    2016-02-02
  • 使用C#生成二维码并插入PDF、Word与Excel文档

    使用C#生成二维码并插入PDF、Word与Excel文档

    二维码在各类文档中广泛应用于链接跳转、身份识别和数据追踪,使用 C# 和 Free Spire.Barcode for .NET,我们可以轻松生成自定义二维码图像,并将其插入到 PDF、Word、Excel 等 Office 文档中,本文将介绍完整的操作过程,需要的朋友可以参考下
    2025-12-12

最新评论