使用WebRequest时BeginGetResponse未触发回调的问题排查
WebRequest.BeginGetResponse回调未执行的原因及解决办法
问题根源
你的代码里,主线程调用GetWebResponse发起异步请求后,直接执行完Console.WriteLine("hax")就结束了进程。而BeginGetResponse属于APM(异步编程模型)模式,回调函数是在后台线程中执行的——一旦主线程退出,整个应用程序进程会直接终止,后台线程还没来得及运行回调就被销毁,所以你看不到回调里的输出内容。
解决办法
要让回调有机会执行,必须让主线程保持运行直到异步操作完成,以下是两种常用方案:
方案1:用ManualResetEvent等待异步操作完成
通过同步信号量控制主线程等待,直到回调执行完毕:
using System; using System.Net; using System.Threading; using Newtonsoft.Json; class X { private static ManualResetEvent _resetEvent = new ManualResetEvent(false); public static void GetWebResponseCallback(IAsyncResult result) { try { Console.WriteLine("test"); WebRequest request = (WebRequest)result.AsyncState; using WebResponse response = request.EndGetResponse(result); Console.WriteLine(JsonConvert.SerializeObject(response)); } finally { // 通知主线程异步操作已完成 _resetEvent.Set(); } } public static void GetWebResponse(string url) { WebRequest request = WebRequest.CreateHttp(url); request.BeginGetResponse(GetWebResponseCallback, request); } public static void Main(string[] args) { var url = "https://github.com/timbrel/GitSavvy/actions/workflows/lint.yml/badge.svg"; GetWebResponse(url); Console.WriteLine("hax"); // 阻塞主线程,等待异步操作完成 _resetEvent.WaitOne(); } }
方案2:让主线程保持运行(适合临时调试)
如果只是用于调试,可以在Main方法末尾添加阻塞主线程的代码,比如读取用户输入:
public static void Main(string[] args) { var url = "https://github.com/timbrel/GitSavvy/actions/workflows/lint.yml/badge.svg"; GetWebResponse(url); Console.WriteLine("hax"); // 等待用户输入,阻止主线程退出 Console.ReadLine(); }
额外注意点
- 原代码中URL末尾多了一个冗余分号,建议修正为正确的字符串格式。
- 调用
EndGetResponse时务必处理异常(比如网络超时、请求失败等),否则未捕获的异常会导致后台线程崩溃。
内容的提问来源于stack exchange,提问作者Hax
相关产品推荐
相关产品推荐

