假设针对某视觉业务场景的方案中原本已搭建了3个流程,分别为流程1、流程2和流程3。随着业务的发展,现需要实现如下多流程控制需求:流程1和流程2都执行1次(不分先后)之后,触发流程3自动执行1次。
由于VM支持执行单个流程和批量执行方案下所有流程,该需求可进一步拆分为2个子需求:
子需求 |
描述 |
---|---|
子需求1 |
流程1和流程2分别执行1次(不分先后)之后,触发流程3自动执行1次。 |
子需求2 |
流程1、流程2和流程3批量执行1次后,触发流程3自动执行1次。 |
方案中多个流程的执行逻辑,可通过全局脚本实现。
具体的实现途径见下图。
基于上述思路,需自行开发全局脚本的代码逻辑实现多流程控制的需求。
已在方案中的搭建3个流程。
本节仅就全局脚本中涉及的核心接口调用做简要介绍。其中SDK的类、方法和属性的详情,请参见VM的SDK开发指南(.NET)。
上述步骤的完整示例代码如下:
using System; using VM.GlobalScript.Methods; using System.Windows.Forms; using iMVS_6000PlatformSDKCS; using System.Runtime.InteropServices; using VM.Core; using VM.PlatformSDKCS; using ImageSourceModuleCs; using IMVSCircleFindModuCs; using VMControls.Interface; using System.Drawing; using System.Drawing.Imaging; using System.Threading.Tasks; /***************************************** * Example explanation:Example of multi process control operation * Logic Control:Single run, each flow execute once * Continuous run:continuous run, each flow execute continuous * 示例说明: 默认代码 * 控制逻辑: 单次运行:所有流程运行一次 * 连续运行:所有流程连续运行 * ***************************************/ public class UserGlobalScript : UserGlobalMethods, IScriptMethods { /// <summary> /// Init /// </summary> /// <returns>Success:return 0</returns> public int Init() { //SDK init int ret = InitSDK(); //InitAfterLoadSol(); if(pro1==null) {pro1 = (VmProcedure)VmSolution.Instance["流程1"];} if(pro2==null) {pro2 = (VmProcedure)VmSolution.Instance["流程2"];} if (pro3 == null) { pro3 = (VmProcedure)VmSolution.Instance["流程3"]; } return ret; } private VmProcedure pro1 = null; private VmProcedure pro2 = null; private VmProcedure pro3 = null; private bool pro1RunEnd = false; private bool pro2RunEnd = false; //加载方案完成触发动作 public override int InitAfterLoadSol() { if(pro1==null) {pro1 = (VmProcedure)VmSolution.Instance["流程1"];} if (pro1 != null) { pro1.OnWorkEndStatusCallBack += Pro1_OnWorkEndStatusCallBack; } if (pro2 == null) { pro2 = (VmProcedure)VmSolution.Instance["流程2"]; } if (pro2 != null) { pro2.OnWorkEndStatusCallBack += Pro1_OnWorkEndStatusCallBack; } if (pro3 == null) { pro3 = (VmProcedure)VmSolution.Instance["流程3"]; } return 0; } private void Pro1_OnWorkEndStatusCallBack(object sender, EventArgs e) { if (e != null) { ValueEventArgs eventArgs = (ValueEventArgs)e; ImvsSdkDefine.IMVS_MODULE_WORK_STAUS status = (ImvsSdkDefine.IMVS_MODULE_WORK_STAUS)eventArgs.Value; //流程1执行完成 if (status.nProcessID == 10000) { pro1RunEnd = true; } else if (status.nProcessID == 10001) { pro2RunEnd = true; } else if (status.nProcessID == 10002) { pro1RunEnd = false; pro2RunEnd = false; } if (pro1RunEnd && pro2RunEnd) { //异步执行一次 pro3.Run("", false); } } } public override void Dispose() { base.Dispose(); if (pro1 != null) { pro1.OnWorkEndStatusCallBack -= Pro1_OnWorkEndStatusCallBack; } if (pro2 != null) { pro2.OnWorkEndStatusCallBack -= Pro1_OnWorkEndStatusCallBack; } } /// <summary> /// execute function /// Single run:the function execute once /// Continuous run:Repeat the function at regular intervals /// 运行函数 /// 单次执行:该函数执行一次 /// 连续执行:以一定时间间隔重复执行该函数 /// </summary> /// <returns>Success:return 0</returns> public int Process() { //m_operateHandle SDK handle if (m_operateHandle == IntPtr.Zero) { return ImvsSdkPFDefine.IMVS_EC_NULL_PTR; } //All processes are executed by default //If execute in your own define logic,please remove the function :DefaultExecuteProcess, Create your own logic function. //默认执行全部流程, //如果自定义流程执行逻辑,请移除DefaultExecuteProcess方法,编写自定义流程执行逻辑代码 int nRet = DefaultExecuteProcess(); return nRet; } }
完成该方案的搭建后,可在VM软件上测试方案效果。
测试场景1:先执行1次流程1,再执行1次流程2。
测试结果:触发流程3执行1次(见如下动图)。
测试场景2:先执行1次流程2,再执行1次流程1。
测试结果:触发流程3执行1次(见如下动图)。
测试场景3:批量同时执行各流程1次
测试结果:流程3在和流程1和流程2同时执行1次的基础上,由于流程1和流程2都执行结束,又被触发执行1次。因此最终流程3在该场景总共执行了2次(见如下动图)。