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

系统关机/注销/重启时SessionEnded事件中HTTP请求未触发的解决方法

关机/注销时发送HTTP请求失败的排查与解决

问题描述

我尝试在系统关机、注销或重启时发送HTTP请求,于是实现了SystemEvents.SessionEnded事件的处理程序:

// main
Microsoft.Win32.SystemEvents.SessionEnded += new SessionEndedEventHandler(Shutdown.ProcessExit);

// Shutdown class
public static void ProcessExit(object sender, EventArgs e){
    File.WriteAllText("path","ProcessExit fired");
    string jsonString = "{}";
    string url= "localurl";
    using (var client = new HttpClient()){
        StringContent stringContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
        var result = await client.PostAsync(url, stringContent);
    }
}

奇怪的是,HTTP请求从未触发(服务器访问日志可以证明),但我确认事件确实被触发了——文件写入操作成功执行,问题只出在HTTP请求上。请问在计算机关机时发送HTTP请求的正确方式是什么?


解决方案与原因分析

这个问题的核心原因是异步操作在关机流程中无法正常完成:

当系统触发SessionEnded事件时,它给应用的处理时间非常有限,而且事件处理线程是系统提供的后台线程。你用了await client.PostAsync(...),这会释放当前线程让系统继续执行关机流程,而异步请求还没来得及完成,进程就被系统终止了,导致请求根本没发出去(或者只发了一半就中断了)。

正确的实现方式

要确保请求能完整发送,你需要同步执行HTTP请求,阻塞线程直到请求完成,同时设置合理的超时时间避免卡住关机流程:

public static void ProcessExit(object sender, EventArgs e)
{
    File.WriteAllText("path", "ProcessExit fired");
    string jsonString = "{}";
    string url = "localurl";
    
    using (var client = new HttpClient())
    {
        // 设置5秒超时,防止因网络问题卡住关机
        client.Timeout = TimeSpan.FromSeconds(5);
        StringContent stringContent = new StringContent(jsonString, Encoding.UTF8, "application/json");
        
        // 使用.Result同步等待请求完成
        var result = client.PostAsync(url, stringContent).Result;
        
        // 可选:记录请求结果,方便排查
        if (result.IsSuccessStatusCode)
        {
            File.AppendAllText("path", "\nRequest sent successfully");
        }
        else
        {
            File.AppendAllText("path", $"\nRequest failed with status: {result.StatusCode}");
        }
    }
}

额外注意事项

  • 不要做耗时操作:关机时系统会快速终止进程,任何超过几秒的操作都可能被强制中断,所以尽量让请求逻辑简洁。
  • 确认目标服务状态:如果是请求本地服务,要确保该服务在关机流程中比你的应用晚终止(否则请求会因为服务已停止而失败)。
  • 权限问题:关机时应用的权限可能受限,确保你的程序有访问目标URL的网络权限,以及写入日志文件的权限。
  • 备选方案:如果需要更可靠的关机触发逻辑(比如处理远程服务器的延迟),可以考虑将请求逻辑封装成Windows服务,服务可以通过ServiceBase.OnShutdown方法处理关机事件,系统会给服务更长的处理时间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:42:28