大家好:我想运行一个功能来检查互联网连接和更新UI内容,所以我在加载的WPF中使用了一个Dispatchtimer,在互联网检查期间,如果ping被本地服务器阻止,或者由于某些x原因UI被阻止。
我怎样才能在不阻塞UI和更新用户界面的情况下连续调用函数?谢谢。
private DispatcherTimer BackgroundAsyncTasksTimer;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BackgroundAsyncTasksTimer = new DispatcherTimer();
BackgroundAsyncTasksTimer.Interval = TimeSpan.FromMilliseconds(2000);
BackgroundAsyncTasksTimer.Tick += BackgroundAsyncTasksTimer_Tick;
BackgroundAsyncTasksTimer.Start();
}
private async void BackgroundAsyncTasksTimer_Tick(object sender, object e)
{
if(CanConnectToTheInternet())
{
Dispatcher.Invoke((Action)delegate () {
einternetcoxn.Fill = (SolidColorBrush)new BrushConverter().ConvertFromString("#00ff00"); //Eclipse
checkNewversion();
bUpdatesoftware.IsEnabled = true;//button
});
}
else
{
Dispatcher.Invoke((Action)delegate () {
einternetcoxn.Fill = (SolidColorBrush)new BrushConverter().ConvertFromString("#841c34");
clearfields();
});
}
}
private static bool CanConnectToTheInternet()
{
try
{
string[] strArray = new string[5]
{
"8.8.8.8",
"https://www.google.com",
"https://www.microsoft.com",
"https://www.facebook.com",
};
if (((IEnumerable<string>)strArray).AsParallel<string>().Any<string>((Func<string, bool>)(url =>
{
try
{
Ping ping = new Ping();
byte[] buffer = new byte[32];
PingOptions options = new PingOptions();
if (ping.Send(url, 500, buffer, options).Status == IPStatus.Success)
return true;
}
catch
{
}
return false;
})))
return true;
if (((IEnumerable<string>)strArray).AsParallel<string>().Any<string>((Func<string, bool>)(url =>
{
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.KeepAlive = false;
httpWebRequest.Timeout = 5000;
using ((HttpWebResponse)httpWebRequest.GetResponse())
return true;
}
catch
{
}
return false;
})))
return true;
}
catch
{
return false;
}
return false;
}
1条答案
按热度按时间xfb7svmp1#
DispatcherTimer * 不是 * 在后台线程上运行tick事件,至少在UI应用程序中默认不是。
但是如果你把你的
CanConnectToTheInternetmethod
改为使用Ping.SendAsync和WebRequest.GetResponseAsync,这应该没问题。这将要求你遵循async await模式,但这是一个很好的例子,说明了这种模式是针对哪类任务的。在这种情况下,你应该去掉所有的Dispatcher.Invoke
-stuff,因为你的所有代码都将在UI线程上运行。另一种方法是使用一个计时器在线程池线程上运行tick-event,如Timers.Timer。