我编写的代码完美无缺,但我担心每2秒ping一次会消耗太多资源,或者会造成互联网连接问题。
new Thread(() =>
{
if (CheckInternetConnection() == false)
{
Dispatcher.Invoke(new Action(delegate
{
//internet access lost
}));
}
else
{
Dispatcher.Invoke(new Action(delegate
{
//internet access
}));
}
Thread.Sleep(2000);
}).Start();
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
public static bool CheckInternetConnection()
{
int output = 0;
return InternetGetConnectedState(out output, 0);
}
这是两个在所有场合都不起作用的事件(仅当IP或网卡发生变化时)
NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged
NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
有人可以帮助我吗?
答案 0 :(得分:2)
注意:注意原始解决方案
NetworkChange.NetworkAvailabilityChanged
工作正常,但是 有一些警告:1)它没有告诉你你是否有 互联网访问,它只是告诉你是否至少有一个 非环回网络适配器工作,2)经常有额外的 出于各种原因安装的网络适配器离开系统 在"网络可用"国家,即使你的主要 互联网连接适配器已禁用/不可用 - 感谢 Peter Duniho
由于网络不仅仅是您的路由器或网卡,而且实际上您可以随时尝试连接到任何地方。最简单,最可靠的方法就是ping谷歌这样的知名来源,或者对你的某个互联网服务使用某种心跳。
这是唯一可靠的方法,原因是您和外界之间可能发生任何数量的连接问题。即使是主要服务提供商也可能会失败。
因此IMCP
ping到已知服务器(如Google)或OpenRead
WebClient
上的using System.Net.NetworkInformation;
// Implementation
using (var ping = new Ping())
{
var reply = ping.Send("www.google.com");
if (reply != null && reply.Status != IPStatus.Success)
{
// Raise an event
// you might want to check for consistent failures
// before signalling a the Internet is down
}
}
// Or if you wanted to get fancy ping multiple sources
private async Task<List<PingReply>> PingAsync(List<string> listOfIPs)
{
Ping pingSender = new Ping();
var tasks = listOfIPs.Select(ip => pingSender.SendPingAsync(ip, 2000));
var results = await Task.WhenAll(tasks);
return results.ToList();
}
是2种有效方法。这些呼叫相对而言并不昂贵,可以用于轻量级计时器或连续任务。
至于你的评论,你可能会发出一个自定义事件的信号,表示在一定数量的安全失败后网络丢失
回答您的问题
但是我担心每2秒ping一次会占用太多资源 可以通过互联网连接制造一些问题。
这两种方法在CPU和网络流量方面都非常便宜,所使用的任何资源都应该非常小
注意:只需确保您正在ping或连接到具有高可用性的服务器, 允许这样的恶作剧,而不仅仅是阻止你
Ping示例
using System.Net;
// Implementation
try
{
using (WebClient client = new WebClient())
{
using (client.OpenRead("http://www.google.com/"))
{
// success
}
}
}
catch
{
// Raise an event
// you might want to check for consistent failures
// before signalling the Internet is down
}
连接示例
async
注意:这两种方法都有一个
Task
变体,它将返回一个SM_CYMENU
可以等待更适合IO绑定任务的Asynchronous programming模式
<强>资源强>
答案 1 :(得分:0)
NetworkInterface.GetIsNetworkAvailable()
不可靠......因为即使所有网络都没有连接到互联网,它也会返回true
。在我看来,检查连接性的最佳方法是ping一个众所周知且快速的在线资源。例如:
public static Boolean InternetAvailable()
{
try
{
using (WebClient client = new WebClient())
{
using (client.OpenRead("http://www.google.com/"))
{
return true;
}
}
}
catch
{
return false;
}
}
无论如何,您订阅的这两个事件并不像您想象的那样工作......实际上它们会检查您的网络适配器的硬件状态......而不是它们是否连接到互联网。它们与NetworkInterface.GetIsNetworkAvailable()
具有相同的缺点。继续检查连接到一个单独的线程,该线程ping一个安全的源并相应地采取行动。您的Interop
解决方案也很出色。
答案 2 :(得分:-1)
对公共资源执行ping操作会给您的应用带来额外的调用,并增加对该网站的依赖性或您在循环中使用的任何内容。
如果您使用此方法怎么办:NetworkInterface.GetIsNetworkAvailable()
?
是否足以满足您应用的用途?