20230109-示波器遗留+DG初步开发

  1. 上上周:示波器触发时间轴

    1. 最初,据杨老师反映,东西两套采集数据时间轴相差0.1ms,互换一台测试后知:CT设置没一样,一个是触发时刻0,另一个触发时刻-0.1

    2. 尝试将触发时刻设置为正,使得示波器触发时间轴前移。尝试了两种方法:正时刻的上升沿信号、零时刻或者正时刻的脉宽信号(会在脉宽信号的下降沿被触发)。实践多次得知,不能在零时刻后被稳定触发,有两种不可干扰:零时刻后的0.1ms内,各种别的动作频繁,干扰很大;即使等待0.1ms后,每次电流过零点,也会产生很大的干扰,该干扰时间无法准确预知。

    3. 最终,保持在零时刻的边沿触发

  2. 上周1:示波器异步中的异常处理

    1. 原始错误代码的简单改写和运行结果如图image.pngimage.png

    2. 对于错误原因的实验结论:

      1. 对于无异常情况,调用一个async函数后,该线程会在遇到await async时继续深入,直到遇到await非async,才一步返回最初的调用者,由该非async线程在执行完自己的任务后逐层收尾await后的代码。图中,Main直接调用DoAsync,DoAsync await SunAsync,SunAsyn先创建新task.run,再await task。image.png

      2. 但是,即使是在async函数的第一次await之前,如果出现(不被async函数自身处理的)异常,线程的控制流会类似于遇到await 非async,留着异常不处理,自身直接返回到最初的调用者,导致异常未被处理从而程序退出,而不是我最初以为的尚在同步部分的异常会普通地返回到调用者try-catch中处理。

      3. 对于错误原因我没有再深挖,再深挖应该是异常的底层机制。我借助猜想做出下述结论:可能由于异常的throw以很高的优先级切换了线程,这对于async执行函数等同一个“可以回了”的信号。

    3. 处理异步异常的方式

      1. 一般可以用事件订阅和ContinueWith等等,为了方便,我选择用后者

      2. 所选的函数签名public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)

      3. 没去深究

        1. Action<Task, object>必须指定一个object的原因

        2. 必需一个TaskScheduler 抽象类的原因

      4. 调用形式

Task t = Task.Factory.StartNew(() => aiTask.Start(), TaskCreationOptions.LongRunning);

t.ContinueWith(new Action<Task, object>(TryRunTask), null,CTSource.Token,TaskContinuationOptions.LongRunning, null);

  1. 上周2:示波器异步中的取消

    1. CancellationTokenSource的简单使用方法:实例化CTS-传递Token-线程负责监听并处理-Cancel-Disposeimage.png

    2. 大致底层逻辑:cancel执行后,取消请求会被传播到所有的Token拷贝值中

    3. Token的多种监听方式(不完整):

      1. 检查IsCancellationRequested属性

      2. 可以Register 多个Action作为source cancel后的callback handler

      3. 有一个method是ThrowIfCancellationRequested(),检查cancel情况,如果有则抛出异常OperationCanceledException。

      4. CTS在cancel后,无法再次使用。之所以需要dispose,是因为它有一些非托管资源。

      5. 比较好奇,但还没深究:CFET2的dispose,只在exit时调用

  2. 上周3:DaqGenerator1.0.1开发

    1. 将开发粗略定为四个阶段性目标:

      1. 1.0:用户指定仅含NI6(也许也兼容NI5)的cards.csv,再加upload.csv,以及简单的config.yml,脚本生成相对死板的thingConfig文件夹

      2. 2.0:新增config.yml,能够指定thingConfig的其他信息;可支持enable;可支持采样率、采样点数/时长的带单位简写

      3. 3.0:新增对Rigol的支持

      4. 4.0:可生成前端文件

    2. 1.0的文档设计

    3. 1.0.1开发步骤:AIThing的生成

      1. 将每个模板json文件作为一个key-value放在model.json中,读入程序成为一个dict

      2. TODO:读取处理config.yml

      3. 从cards.csv读得每张卡的关键配置,据此对dict[AIThing]稍加修改,即可依次dump出一个AIThing的配置文件

      4. TODO:注意生成文件的所在目录

  3. 上述示波器修改还未到现场调试

  4. 一点感悟:按照二八定律先抓重点,后续再根据实际情况去完善