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

C#控制台程序线程调用HttpClient.GetAsync无响应问题排查

问题:C#控制台调用HttpClient异步方法时程序直接退出,无法获取响应

在C#控制台程序中测试HttpClient相关方法,执行CallPythonApiGet方法时程序直接退出,无法获取响应结果。怀疑线程与Task await存在冲突或非主线程导致问题,希望排查代码误用点。

相关代码

Program.cs

using System;
using System.Threading;
using AutoProcessWorks;

_AutoProcessWorks autoProcessWorks = new _AutoProcessWorks();
Thread AutoRunThread = new Thread(new ThreadStart(autoProcessWorks.MainRun));
AutoRunThread.Start();

AutoProcessWorks.cs

public class _AutoProcessWorks
{
    Api api = new Api();
    SqlTools sqlTools = new SqlTools();
    public bool Switch_Run = true;
    public void MainRun()
    {
        int sleep = 60000;
        Api api = new Api();
        while (Switch_Run)
        {
            var route = "IsNFTContractEnough";
            var res = api.CallPythonApiGet(route);
            Console.WriteLine(res);
            Switch_Run = false;
        }
    }
}

public class Api
{
    public async Task<string> CallPythonApiGet(string route)
    {
        const string uri = "http://127.0.0.1:5000/";
        using (HttpClient client = new HttpClient())
        {
            var respones_result = "";
            try
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                client.Timeout = TimeSpan.FromSeconds(600);
                var response = await client.GetAsync(uri + route);
                respones_result = response.Content.ReadAsStringAsync().Result;
                response.EnsureSuccessStatusCode();
                string responseBody = await response.Content.ReadAsStringAsync();
                return responseBody;
            }
            catch (HttpRequestException e)
            {
                var error = "";
                error += respones_result + "\n\r";
                error += "\nException Caught! Message :" + e.Message;
                return error;
            }
        }
    }
}

代码误用点排查与修复

核心问题1:主线程提前退出终止整个程序

控制台程序的主线程是进程的入口,主线程执行完毕后,整个进程会直接终止,不管子线程是否完成任务。当前Program.cs中启动子线程后没有任何等待逻辑,主线程直接结束,导致子线程的异步请求还没完成就被强制终止。

核心问题2:异步方法未正确等待,Task被丢弃

CallPythonApiGet是异步方法,返回Task<string>,但MainRun中直接调用而未用await等待完成,此时代码会立即返回一个未完成的Task对象,Console.WriteLine(res)打印的是Task的ToString结果而非实际响应,同时异步操作还没执行完程序就已经退出。

另外,CallPythonApiGet内部用response.Content.ReadAsStringAsync().Result同步阻塞调用,可能引发死锁,应该统一使用await。


修复方案一:让主线程等待子线程完成

修改Program.cs,添加线程等待逻辑:

using System;
using System.Threading;
using AutoProcessWorks;

_AutoProcessWorks autoProcessWorks = new _AutoProcessWorks();
Thread AutoRunThread = new Thread(new ThreadStart(autoProcessWorks.MainRun));
AutoRunThread.Start();
AutoRunThread.Join(); // 阻塞主线程,直到子线程执行完毕

同时修改MainRun为异步方法,正确等待请求结果:

public async void MainRun()
{
    int sleep = 60000;
    Api api = new Api();
    while (Switch_Run)
    {
        var route = "IsNFTContractEnough";
        var res = await api.CallPythonApiGet(route); // await等待异步请求完成
        Console.WriteLine(res);
        Switch_Run = false;
    }
}

修复方案二:使用异步主线程(推荐写法)

现代C#控制台支持异步Main方法,无需手动创建线程:
修改Program.cs:

using System;
using System.Threading.Tasks;
using AutoProcessWorks;

await new _AutoProcessWorks().MainRunAsync();
Console.ReadKey(); // 可选,防止执行完毕后直接退出

修改_AutoProcessWorks的方法:

public class _AutoProcessWorks
{
    Api api = new Api();
    SqlTools sqlTools = new SqlTools();
    public bool Switch_Run = true;
    public async Task MainRunAsync() // 用async Task替代async void,便于异常处理
    {
        int sleep = 60000;
        Api api = new Api();
        while (Switch_Run)
        {
            var route = "IsNFTContractEnough";
            var res = await api.CallPythonApiGet(route);
            Console.WriteLine(res);
            Switch_Run = false;
        }
    }
}

同时修复Api类中的同步阻塞问题:

public async Task<string> CallPythonApiGet(string route)
{
    const string uri = "http://127.0.0.1:5000/";
    using (HttpClient client = new HttpClient())
    {
        var respones_result = "";
        try
        {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.Timeout = TimeSpan.FromSeconds(600);
            var response = await client.GetAsync(uri + route);
            response.EnsureSuccessStatusCode(); // 先验证请求成功
            string responseBody = await response.Content.ReadAsStringAsync();
            return responseBody;
        }
        catch (HttpRequestException e)
        {
            var error = "";
            error += respones_result + "\n\r";
            error += "\nException Caught! Message :" + e.Message;
            return error;
        }
    }
}

额外优化建议

  • HttpClient无需每次请求创建,建议全局单例复用,避免频繁创建释放连接导致性能损耗。
  • 尽量避免使用async void,优先用async Task,方便控制异步流程和捕获异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:36:20