Home > database >  DispatchTimer blocks UI
DispatchTimer blocks UI

Time:12-10

Hi All: I want to run a function to check internet connection and update the UI content, so i'm using a Dispatchtimer in the WPF loaded, during the intenet check if the ping is blocked by the local server or for some x reasons the UI is blocking.

How can i call the function continuosly without blocking the UI & update the User interface? thanks.

 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;
        }

CodePudding user response:

A DispatcherTimeris not running the tick event on a background thread, at least not by default in a UI application.

But this should be fine if you change your CanConnectToTheInternetmethod to use Ping.SendAsync and WebRequest.GetResponseAsync. That will require you to follow the async await pattern, but this is an good example of the kind of task this pattern is meant for. In this case you should get rid of all the Dispatcher.Invoke-stuff, since all of your code would run on the UI thread.

The alternative would be to use a timer that runs the tick-event on a threadpool thread, like Timers.Timer. See also timer comparison

  • Related