经过多次迭代后,WPF Textblock的更新失败了吗?

时间:2012-01-14 19:51:16

标签: wpf user-interface

我在使用更改值(最终将通过网络流式传输)更新TextBlock时遇到了一个特殊问题。这是与其他人在此论坛上遇到的类似问题,除了下面的测试解决方案最初工作(即计时器成功更新textBlock1.text然后正确显示)但在经过一定次数的迭代后(通常在200和300)。无论我处理线程的方式如何,我想我做错了。

我是C#,。Net和线程的新手,所以我们非常感谢任何建议。

namespace TestWPF_WorkerThreads
{
    MainWindow : Window
    {
        private int counter = 0;
        private string counterText="";

        public MainWindow()
        {
            InitializeComponent();
            Timer myTimer = new Timer(Work, counterText, 1000, 100);

        }

        void Work(Object message)
        {
            counter++;
            counterText = counter.ToString();
            string temp = message.ToString();
            temp = temp + counterText;
            Thread.Sleep(100);
            UpdateMessage(temp);
        }

        void UpdateMessage(string msg)
        {
            Action action = () => textBlock1.Text = msg;
            Dispatcher.Invoke(action);

        }
    }
}

2 个答案:

答案 0 :(得分:1)

你有一个周期为100毫秒的计时器,它调用的代码包含一个等待100毫秒的'sleep'。这听起来不错!

您应该阅读此excellent article on timers on MSDN,您会看到无论您是否“睡觉”,您使用的System.Threading.Timer都会继续点火。使用WPF,最好使用在UI线程上触发的DispatcherTimer类。

答案 1 :(得分:0)

这是经过调整的程序,它继续成功更新TextBlock:

namespace TestWPF_WorkerThreads
{

    public partial class MainWindow : Window
    {
        System.Timers.Timer aTimer;
        private int counter = 0;
        private string counterText="";

        public MainWindow()
        {
            InitializeComponent();                              // -- SOLUTION --
            aTimer = new System.Timers.Timer(10);               // Used a System.Timer.Timer Class
            aTimer.Elapsed += new ElapsedEventHandler(Work);    // instead of the 
            aTimer.Enabled = true;                              // System.Threading.Timer Class

        }

        void Work(object source, ElapsedEventArgs e)
        {
            aTimer.Enabled = false;                             // and made use of the Enabled property to stop
            counter++;                          
            counterText = counter.ToString();   
            string temp = "Tick: ";             
            temp = temp + counterText;          
            Thread.Sleep(10);                   
            UpdateMessage(temp);               
            aTimer.Enabled = true;                              // and start the timer while the textBlock is updated
        }


        void UpdateMessage(string msg)
        {
            Action action = () => textBlock1.Text = msg;
            Dispatcher.Invoke(action);

        }
    }
}