DispatchTimer blocks UI



嗨,我想运行一个函数来检查互联网连接和更新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;
}

DispatcherTimeris在后台线程上运行tick事件,至少在UI应用程序中不是默认的。

但这应该是好的,如果你改变你的CanConnectToTheInternetmethod使用Ping。SendAsync和WebRequest.GetResponseAsync。这将要求您遵循异步等待模式,但这是该模式所适用的任务类型的一个很好的示例。在这种情况下,你应该摆脱所有的Dispatcher.Invoke-东西,因为你所有的代码将运行在UI线程上。

另一种方法是使用定时器在线程池线程上运行tick-event,如Timers.Timer。参见定时器比较

最新更新