Обновление WPF Texblock не удается после нескольких итераций? - PullRequest
0 голосов
/ 14 января 2012

У меня есть особая проблема с обновлением 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 ]

1 голос
/ 15 января 2012

У вас есть таймер с периодом 100 миллисекунд, и код, который он вызывает, содержит «спящий» режим, который ждет 100 миллисекунд. Это звучит неправильно!

Вам следует прочитать эту отличную статью о таймерах на MSDN , вы увидите, что System.Threading.Timer, который вы используете, продолжает срабатывать независимо от того, спите ли вы. С WPF гораздо лучше использовать класс DispatcherTimer, который запускается в потоке пользовательского интерфейса.

0 голосов
/ 15 января 2012

Вот настроенная программа, которая продолжает успешно обновлять 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);

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...