You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#多线程并行测试代码正确性咨询,Async异步编程相关问题

代码合理性点评

你的核心观测思路是通顺的,就是通过记录异步任务的启动、完成时间点来对比并行执行的耗时表现,但代码里存在几个明显的设计缺陷和使用误区:

  • Parallel.For的滥用:Parallel类是专为CPU密集型同步任务设计的并行调度工具,你这里的核心逻辑是异步IO任务(Task.Delay模拟),Parallel.For执行完成仅代表所有StartAThread方法执行完毕(即所有任务标记为Started存入字典),不会等待你启动的异步StartOperation执行完成,此时直接点击报表按钮大概率会出现启动记录远多于完成记录的情况。而且Parallel.For会阻塞UI线程,点击启动按钮后窗口会直接假死直到所有启动逻辑跑完。
  • 异步任务的生命周期管理缺失:你用ContinueWith捕获异步结果,一是没有做异常处理,如果StartOperation执行抛出异常,访问result.Result会直接触发未捕获的AggregateException导致程序崩溃;二是没有留存所有异步任务的引用,无法判断所有任务是否全部执行完成,也没法做统一等待逻辑。
  • 冗余代码问题:TestThreadClass中的私有字段myTask没有任何实际作用,赋值后仅做了一次await,完全可以删掉,直接在StartOperation里返回await InvokeOperation()即可。
  • 精度干扰问题:Task.Delay(1)的实际精度受系统计时器限制,Windows系统默认计时器精度为10~15ms,所以你设置的1ms延迟实际会等待10ms左右,观测结果会有误差。
  • WinForms UI线程安全隐患:当前你在UI线程触发的BtnReport_Click中操作DataGridView没有问题,但如果后续要做异步任务全部完成后自动更新UI的逻辑,直接在非UI线程操作控件会抛出跨线程访问异常,需要用Control.Invoke切换回UI线程再操作控件。
改进建议
  • 把Parallel.For替换成普通循环批量创建异步任务,把所有返回的Task存到一个列表里,可通过await Task.WhenAll(任务列表)等待所有异步任务全部执行完成,整个过程不会阻塞UI线程。
  • 把ContinueWith替换成await写法,代码可读性更高,异常处理也更简单,直接用try-catch包裹即可捕获异步逻辑的异常。
  • 每次点击启动按钮前先清空两个ConcurrentDictionary,避免多次启动的数据混杂影响观测结果。
  • 可以把延迟时间调整到100ms以上,规避系统计时器精度带来的测试误差。

内容的提问来源于stack exchange,提问作者canowar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:24:03