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

如何用C#的Process类判断dotnet服务器进程已完全启动?

解决方案

方案1:监听服务器输出日志

服务器启动成功时通常会在控制台输出特定标识(比如Now listening on: http://localhost:5000),可以通过捕获进程输出流判断启动状态。注意需将UseShellExecute设为false以支持输出重定向:

var processStartInfo = new ProcessStartInfo()
{
    FileName = @"dotnet",
    WorkingDirectory = path,
    UseShellExecute = false, // 必须关闭ShellExecute才能重定向输出
    RedirectStandardOutput = true,
    Arguments = $"run --project {projectName}",
    CreateNoWindow = true // 可选,隐藏服务器控制台窗口
};

using var process = Process.Start(processStartInfo);
// 异步读取完整输出,避免阻塞主线程
var fullOutputTask = process.StandardOutput.ReadToEndAsync();

// 逐行检查输出中的启动成功标识
while (!fullOutputTask.IsCompleted)
{
    var line = process.StandardOutput.ReadLine();
    if (line != null && line.Contains("Now listening on:"))
    {
        // 服务器已启动完成
        break;
    }
    // 短时间休眠降低CPU占用
    await Task.Delay(100);
}

// 执行后续逻辑

方案2:轮询服务器端口/健康检查接口

若已知服务器监听端口,或服务器提供健康检查接口,可通过定期尝试连接判断启动状态:

端口轮询示例

using var process = Process.Start(processStartInfo);
var targetPort = 5000; // 服务器监听的端口
var maxRetry = 30; // 最大尝试次数
var retryCount = 0;
var isReady = false;

while (retryCount < maxRetry)
{
    try
    {
        using var client = new TcpClient();
        await client.ConnectAsync("localhost", targetPort);
        isReady = true;
        break;
    }
    catch (SocketException)
    {
        // 端口未就绪,继续等待
        await Task.Delay(500);
        retryCount++;
    }
}

if (!isReady)
{
    throw new TimeoutException("服务器启动超时");
}

健康检查接口轮询示例

using var process = Process.Start(processStartInfo);
var healthUrl = "http://localhost:5000/health";
var httpClient = new HttpClient();
var maxRetry = 30;
var retryCount = 0;
var isReady = false;

while (retryCount < maxRetry)
{
    try
    {
        var response = await httpClient.GetAsync(healthUrl);
        if (response.IsSuccessStatusCode)
        {
            isReady = true;
            break;
        }
    }
    catch (HttpRequestException)
    {
        // 接口未就绪,继续等待
        await Task.Delay(500);
        retryCount++;
    }
}

if (!isReady)
{
    throw new TimeoutException("服务器启动超时");
}

方案3:进程间通信(IPC)通知

若可修改服务器项目,可在启动完成后通过IPC机制(如命名信号量、管道)主动通知启动程序:

服务器端代码(启动完成后执行)

// 创建命名信号量并释放,标记启动完成
using var semaphore = new Semaphore(0, 1, "ServerStartupCompleted");
semaphore.Release();

启动程序端代码

using var process = Process.Start(processStartInfo);
// 等待信号量,设置30秒超时
if (!Semaphore.WaitOne(TimeSpan.FromSeconds(30)))
{
    throw new TimeoutException("服务器启动超时");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:35:04