如何取消不支持CancellationTokenSource的SendPingAsync?附检测代码
如何取消不支持CancellationToken的Ping.SendPingAsync操作
好问题!确实,早期版本的Ping.SendPingAsync没有直接提供支持CancellationToken的重载,但我们有几种可靠的方式来实现异步操作的取消逻辑,下面是两种实用方案:
方案1:使用Task.WhenAny实现逻辑取消(兼容所有.NET版本)
思路是同时运行Ping任务和一个绑定取消令牌的延迟任务,哪个先完成就优先处理哪个。这样当取消令牌被触发时,我们可以立即终止等待,不用等Ping操作完成,达到逻辑上的取消效果。
代码示例:
public static async Task<bool> PingServer(CancellationToken cancellationToken) { using var pinger = new System.Net.NetworkInformation.Ping(); // 启动Ping任务 var pingTask = pinger.SendPingAsync("pc2"); // 等待Ping完成,或者取消令牌被触发 var completedTask = await Task.WhenAny(pingTask, Task.Delay(Timeout.Infinite, cancellationToken)); // 如果完成的是取消任务,处理取消逻辑 if (completedTask != pingTask) { // 可以选择抛出取消异常,或者直接返回false,根据你的业务需求来 cancellationToken.ThrowIfCancellationRequested(); return false; } // 处理Ping结果 var pingReply = await pingTask; return pingReply.Status == System.Net.NetworkInformation.IPStatus.Success; }
注意:这种方式不会主动终止底层的Ping操作,但会让你的代码不再等待它的结果,对于大多数业务场景来说已经足够。
方案2:使用WaitAsync(适用于.NET 5+)
如果你使用的是.NET 5或更高版本,可以利用Task的WaitAsync扩展方法,它直接支持传入CancellationToken,写法更简洁:
代码示例:
public static async Task<bool> PingServer(CancellationToken cancellationToken, int pingTimeout = 5000) { using var pinger = new System.Net.NetworkInformation.Ping(); var pingTask = pinger.SendPingAsync("pc2", pingTimeout); try { // 等待Ping完成,同时监听取消令牌 await pingTask.WaitAsync(cancellationToken); } catch (OperationCanceledException) { // 捕获取消异常,返回false或者抛出异常,按需处理 return false; } return pingTask.Result.Status == System.Net.NetworkInformation.IPStatus.Success; }
这个方法同样是逻辑取消,但代码结构更清晰,还能同时设置Ping本身的超时时间,一举两得。
另外别忘了用using包裹Ping对象,确保网络资源被正确释放哦!
内容的提问来源于stack exchange,提问作者Mamad
相关产品推荐
相关产品推荐

