c#wpf在单独的线程上触发dispatcherTimer(应该更新UI) [英] c# wpf firing dispatcherTimer on separate thread(should update UI)

查看:135
本文介绍了c#wpf在单独的线程上触发dispatcherTimer(应该更新UI)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


Hello

Hello


我正在研究wpf应用程序,我需要在UI上显示正确的时间,所以我的想法是创建我的DateAndTime类将运行的单独线程,因为我的主线程太忙了。我读到了DispatcherTimer,但我不能让它在单独的
线程上运行,它只是第一次触发然后停止(它在主线程上运行,但UI是无响应的方式)。我在stackoverflow等上搜索了很多但是找不到工作示例。

I am working on wpf application where I need to show correct time on UI,so my idea was to create separate thread where my DateAndTime class will be running, because my main thread is too busy. I read about DispatcherTimer but i just cant get it working on separate thread, it fires only first time and then stops(It works on main thread,but UI is way to unresponsive). I searched alot on stackoverflow etc. but cant find working example.


有人可以在wpf应用程序中编写关于计时器如何在单独的线程上工作的示例(非常简单)或者只是指出我做错了什么。

Can someone write example(very simple) on how timer would work on separate thread,in wpf application,or just point me what im doing wrong.



谢谢


class DateAndTime
    {
        DateTime dateTimeGlobal = DateTime.MinValue;
        MainWindow mw = (MainWindow)App.Current.MainWindow;

        private DispatcherTimer RefreshTimer;
        public System.Timers.Timer RefresTimernew;
        bool call = true;

        public void GetTime()
        {
            DateTime dateTime = DateTime.MinValue;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://nist.time.gov/actualtime.cgi?lzbc=siqm9b");

            request.Method = "GET";
            request.Accept = "text/html, application/xhtml+xml, */*";
            request.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
            ServicePointManager.Expect100Continue = true;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                StreamReader stream = new StreamReader(response.GetResponseStream());

                string html = stream.ReadToEnd();
                string time = Regex.Match(html, @"(?<=\btime="")[^""]*").Value;
                double milliseconds = Convert.ToInt64(time) / 1000.0;

                dateTime = new DateTime(1970, 1, 1).AddMilliseconds(milliseconds).ToLocalTime();
            }

            dateTimeGlobal = dateTime;
            SetDateDayTime();
            if (call)
            {
                RefreshTimer1();
                call = false;
            }
            Thread.Sleep(1000 - dateTime.Millisecond);
            InitTimer(new TimeSpan(0, 0, 0));        //ako bude freezalo,postavi da se timer pokrece svakih x sekundi,bez prve linije u RefreshTimerTick metodi
        }
        #region Timer za refreshanje Time textblocka
        private void InitTimer(TimeSpan t)
        {
            RefreshTimer = new DispatcherTimer(DispatcherPriority.Background);
            RefreshTimer.Tick += new EventHandler(RefreshTimerTick);
            RefreshTimer.Interval = t;
            RefreshTimer.Start();
        }
        private void RefreshTimerTick(object sender,EventArgs e)
        {
            ((DispatcherTimer)sender).Interval = new TimeSpan(0, 0, 60);
            GetTime();
        }
        private void RefreshTimer1()
        {
            var timer = new System.Threading.Timer(e => GetTime(), null, 0, 6000);
        }
        #endregion
        #region Postavljanje texblockova za dan,datum i vrijeme
        private void SetDateDayTime()
        {
            string Day="",Time;
            switch(dateTimeGlobal.DayOfWeek.ToString())
            {
                case "Monday": Day = "Ponedjeljak";
                        break;
                case "Tuesday": Day = "Utorak";
                        break;
                case "Wednesday": Day = "Srijeda";
                        break;
                case "Thursday": Day = "Četvrtak";
                        break;
                case "Friday": Day = "Petak";
                        break;
                case "Saturday": Day = "Subota";
                        break;
                case "Sunday": Day = "Nedjelja";
                        break;

            }
            if(dateTimeGlobal.Minute/10==0)
                Time = dateTimeGlobal.Hour.ToString() + ":0" + dateTimeGlobal.Minute.ToString();
            else
                Time = dateTimeGlobal.Hour.ToString() + ":" + dateTimeGlobal.Minute.ToString();
            mw.SetDateDayTimeTexblocks(dateTimeGlobal.ToShortDateString(),Day,Time);
        }
        #endregion 
    }

以下是在主线程上运行的代码的一部分(与此相关的部分)

Here is part of code that runs on main thread(part that is related to this)

//this is in constructor,it runs when program is opened
  public partial class MainWindow : Window
    {
        private delegate void UpdateDateDayCallback(string Date,string Day,string Time);
        private delegate void UpdateDateTimeCallback(string Time);
            public MainWindow()
        {
            this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
            InitializeComponent();
            DateAndTime dt = new DateAndTime();
            Thread DateTimeThread = new Thread(dt.GetTime);
            DateTimeThread.IsBackground = true;
            DateTimeThread.Start();
        }
        //these two methods are for updating textblocks from 
        //separate thread

        public void SetDateDayTimeTexblocks(string Date,string Day,string Time)
        {
            if (!Dispatcher.CheckAccess())
            {
                UpdateDateDayCallback dg = new UpdateDateDayCallback(this.SetDateDayTimeTexblocks);
                DayTextBlock.Dispatcher.Invoke(dg, new object[] { Date, Day,Time });
            }
            else
            {
                DateTextBlock.Text = Date;
                DayTextBlock.Text = Day;
                TimeTextBlock.Text = Time;
            }
        }
}
// and i have 2 delegates defined





推荐答案

你的DateAndTime .GetTime方法运行一次然后退出。 谁将重启?

Your DateAndTime.GetTime method runs once then exits.  Who is going to restart it?

你应该让GetTime成为一个无限循环。 让它永远运行,最后睡眠(1000)。 您可能希望让它检查"线程退出"。您可以在关机时设置的标志。

You should make GetTime an infinite loop.  Just let it run forever, with a Sleep(1000) at the very end.  You might want to have it check for a "thread exit" flag that you can set at shutdown.

或者,您可以在主循环中使用普通的1秒计时器,并触发"新线程(dt.GetTime)"。每次你勾选。

Alternatively, you can use an ordinary 1 second timer in your main loop, and fire off "new Thread(dt.GetTime)" each time you get a tick.


这篇关于c#wpf在单独的线程上触发dispatcherTimer(应该更新UI)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆