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

如何在C#单元测试中正确调用Nethereum的GetTransactionCount异步方法

解决异步获取TransactionCount的单元测试问题

首先,你的单元测试里用Wait()是核心问题之一——在异步方法里直接调用Wait()很容易引发死锁,还没法正确拿到异步任务的结果。咱们可以通过下面几个步骤来修复:

1. 用await替代Wait()调用异步方法

你的单元测试方法已经标记为async Task,直接用await就能获取GetTxCount的结果,完全不需要手动调用Wait():

[TestMethod]
public async Task TestMethodAsync() 
{ 
    string address = "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae"; 
    EthTest.Eth et = new EthTest.Eth(); 
    // 用await获取异步结果,这里可以强转成ulong(交易数量是无符号整数类型)
    var txCount = await et.GetTxCount(address).ConfigureAwait(false); 
    // 可以加个断言验证结果合理性,比如交易数不会是负数
    Assert.IsTrue((ulong)txCount >= 0);
}

2. 优化GetTxCount的返回类型

你现在的GetTxCount返回Task<object>,其实可以更明确地返回Task<ulong>,这样单元测试里不用强制转换,代码也更清晰:

public async Task<ulong> GetTxCount(string address) 
{ 
    return await web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(address).ConfigureAwait(false); 
}

对应的单元测试可以简化成:

[TestMethod]
public async Task TestMethodAsync() 
{ 
    string address = "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae"; 
    EthTest.Eth et = new EthTest.Eth(); 
    ulong txCount = await et.GetTxCount(address).ConfigureAwait(false); 
    Assert.IsTrue(txCount >= 0);
}

3. 排查Web3实例的初始化问题

如果改完还是没调用Nethereum的API,那大概率是EthTest.Eth类里的web3实例没正确初始化。一定要确保你连接到了有效的以太坊节点,比如在类的构造函数里初始化:

public Eth()
{
    // 替换成你的节点地址,比如Infura的主网/测试网节点,或者本地Ganache节点
    string nodeUrl = "https://mainnet.infura.io/v3/你的项目ID";
    web3 = new Web3(nodeUrl);
}

要是节点地址无效或者没网络,SendRequestAsync会直接失败,看起来就像没调用API一样。可以在单元测试里加个异常捕获,方便排查具体错误:

[TestMethod]
public async Task TestMethodAsync() 
{ 
    try
    {
        string address = "0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae"; 
        EthTest.Eth et = new EthTest.Eth(); 
        ulong txCount = await et.GetTxCount(address).ConfigureAwait(false); 
        Assert.IsTrue(txCount >= 0);
    }
    catch(Exception ex)
    {
        // 打印异常信息,方便定位问题
        Console.WriteLine($"出错了:{ex.Message}");
        throw; // 重新抛出异常让单元测试失败,同时保留错误详情
    }
}

为啥Wait()会出问题?

在有SynchronizationContext的环境(比如部分单元测试框架)里,Task.Wait()会阻塞当前线程,而异步任务完成后需要回到原来的上下文,这就会造成死锁——阻塞的线程等着任务完成,任务又等着阻塞的线程释放上下文。用await则会正确释放上下文,从根源避免死锁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:28:36