wpf 调度计时器阻止UI

c0vxltue  于 2022-12-14  发布在  其他
关注(0)|答案(1)|浏览(180)

大家好:我想运行一个功能来检查互联网连接和更新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;
        }
xfb7svmp

xfb7svmp1#

DispatcherTimer * 不是 * 在后台线程上运行tick事件,至少在UI应用程序中默认不是。
但是如果你把你的CanConnectToTheInternetmethod改为使用Ping.SendAsyncWebRequest.GetResponseAsync,这应该没问题。这将要求你遵循async await模式,但这是一个很好的例子,说明了这种模式是针对哪类任务的。在这种情况下,你应该去掉所有的Dispatcher.Invoke-stuff,因为你的所有代码都将在UI线程上运行。
另一种方法是使用一个计时器在线程池线程上运行tick-event,如Timers.Timer

相关问题