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

单元测试问题:如何确保断言前等待所有线程执行完成?

问题根源

你遇到的核心问题是:用Thread执行async void委托时,线程会在await处提前退出。thread.Join()只能等待线程本身的执行流程结束,而不等await之后的异步逻辑完成,导致断言时部分GetMemoryAsync()还没执行完毕,断言失败。

解决方案

方案1:改用Task(推荐,符合异步编程最佳实践)

直接使用Task管理异步操作,用Task.WhenAll等待所有任务完成,同时将测试方法改为async Task类型:

[Test]
public async Task Test_Racing_Condition()
{
    //Arrange & Act
    var tasks = new Task[20];
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i] = _memory.GetMemoryAsync();
    }
    // 等待所有异步任务完成
    await Task.WhenAll(tasks);

    //Assert
    Mock.Assert(() => _memory.GetMemoryAsync(), Occurs.Exactly(20));
}

方案2:如果必须用Thread,同步等待异步方法

避免使用async void,在Thread内部同步等待异步方法完成,确保线程会等到GetMemoryAsync()执行完再结束:

[Test]
public void Test_Racing_Condition()
{
    //Arrange & Act
    var threads = new Thread[20];
    for (int i = 0; i < threads.Length; i++)
    {
        // 用.GetAwaiter().GetResult()同步等待异步方法完成,防止线程提前退出
        threads[i] = new Thread(() => _memory.GetMemoryAsync().GetAwaiter().GetResult());
    }
    foreach (Thread thread in threads)
    {
        thread.Start();
    }
    foreach (var thread in threads)
    {
        thread.Join();
    }

    //Assert
    Mock.Assert(() => _memory.GetMemoryAsync(), Occurs.Exactly(20));
}
关键说明
  • async void仅适用于事件处理程序,在Thread委托这类场景中会导致异步操作不受跟踪,线程提前终止。
  • 异步测试优先采用async Task类型的测试方法,配合Task.WhenAll是最可靠的异步等待方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:05:25