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

多线程应用中调用API时如何持续检测网络连接?

我来给你几个实用的解决方案,刚好匹配你的需求:

1. 靠谱的网络状态检测方法

首先你需要一个准确的方法判断网络是否可用——单纯用NetworkInterface.GetIsNetworkAvailable()有时候会误判(比如网卡插着但没联网),所以我们可以写一个更严谨的版本:

using System.Net.NetworkInformation;
using System.Linq;

private bool IsNetworkAvailable()
{
    // 遍历所有非回环、非隧道的网络接口
    foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces())
    {
        // 接口必须处于启用状态,且有有效的IPv4/IPv6地址
        if (networkInterface.OperationalStatus == OperationalStatus.Up &&
            networkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
            networkInterface.NetworkInterfaceType != NetworkInterfaceType.Tunnel)
        {
            var ipProps = networkInterface.GetIPProperties();
            if (ipProps.UnicastAddresses.Any(ua => 
                ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ||
                ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6))
            {
                return true;
            }
        }
    }
    return false;
}
2. 等待网络恢复的逻辑

如果检测到网络不可用,我们需要暂停等待,但不能让线程空转占用CPU。这里提供同步和异步两种版本:

同步版本(适合ThreadPool的传统用法)

private void WaitForNetwork()
{
    // 每5秒检查一次网络状态,避免CPU空转
    while (!IsNetworkAvailable())
    {
        System.Threading.Thread.Sleep(5000);
    }
}

异步版本(推荐,更高效)

private async System.Threading.Tasks.Task WaitForNetworkAsync(System.Threading.CancellationToken cancellationToken = default)
{
    while (!IsNetworkAvailable())
    {
        await System.Threading.Tasks.Task.Delay(5000, cancellationToken);
        cancellationToken.ThrowIfCancellationRequested();
    }
}
3. 结合ThreadPool的完整调用逻辑

另外注意你的原API代码有资源泄漏风险——HttpWebResponse和StreamReader必须用using包裹,确保资源被正确释放。下面是整合后的代码:

传统ThreadPool版本

// 封装API请求,确保资源释放
private void MakeApiRequest()
{
    try
    {
        string url = settings.Get("URL");
        using (var httpRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url))
        {
            httpRequest.Method = "GET";
            using (var res = (System.Net.HttpWebResponse)httpRequest.GetResponse())
            using (var sr = new System.IO.StreamReader(res.GetResponseStream(), System.Text.Encoding.Default))
            {
                string response = sr.ReadToEnd();
                // 在这里处理API返回的内容,比如解析、存储等
            }
        }
    }
    catch (System.Net.WebException ex)
    {
        // 处理请求异常,比如网络中途断开的情况
        System.Console.WriteLine($"API请求失败: {ex.Message}");
        // 可以根据需要添加重试逻辑
    }
}

// 提交到ThreadPool的工作项
private void ApiWorkItem(object state)
{
    // 先等待网络恢复
    WaitForNetwork();
    // 网络可用后发起请求
    MakeApiRequest();
}

// 调用方式
System.Threading.ThreadPool.QueueUserWorkItem(ApiWorkItem);

异步Task版本(推荐,更符合.NET现代编程模式)

如果可以的话,用Task.Run代替ThreadPool的旧方法(内部还是用ThreadPool,但异步支持更好):

// 异步API请求方法
private async System.Threading.Tasks.Task MakeApiRequestAsync()
{
    try
    {
        string url = settings.Get("URL");
        using (var httpRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url))
        {
            httpRequest.Method = "GET";
            using (var res = (System.Net.HttpWebResponse)await httpRequest.GetResponseAsync())
            using (var sr = new System.IO.StreamReader(res.GetResponseStream(), System.Text.Encoding.Default))
            {
                string response = await sr.ReadToEndAsync();
                // 处理返回内容
            }
        }
    }
    catch (System.Net.WebException ex)
    {
        System.Console.WriteLine($"API请求失败: {ex.Message}");
    }
}

// 异步工作项
private async System.Threading.Tasks.Task ApiWorkItemAsync()
{
    await WaitForNetworkAsync();
    await MakeApiRequestAsync();
}

// 调用方式
_ = System.Threading.Tasks.Task.Run(ApiWorkItemAsync);
4. 进阶优化:事件驱动的网络监听

如果不想轮询网络状态,可以用.NET自带的网络变化事件,这样网络恢复时立即触发请求,更高效:

// 在应用启动时注册事件
System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;

private void NetworkChange_NetworkAvailabilityChanged(object sender, System.Net.NetworkInformation.NetworkAvailabilityEventArgs e)
{
    if (e.IsAvailable)
    {
        System.Console.WriteLine("网络已恢复,开始发起API请求");
        System.Threading.ThreadPool.QueueUserWorkItem(ApiWorkItem);
    }
    else
    {
        System.Console.WriteLine("网络已断开,暂停API请求");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:13