如何在BeginInvoke中使用Thread.Sleep

时间:2012-12-14 08:06:50

标签: c# wpf multithreading dispatcher

我尝试使用以下代码更新 TextBox.Text ,以1到10的内部显示,内部为1秒。我不明白为什么整个UI在文本更新到10之前会休眠10秒,因为我虽然 Thread.Sleep(1000)应该属于由 Dispatcher创建的单独的后台线程.BeginInvoke 即可。

我的代码出了什么问题?

Thread t1 = new Thread(new ThreadStart(
    delegate()
    {
        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
            new Action(delegate()
                {
                    for (int i = 1; i < 11; i++)
                    {
                        mytxt1.Text = "Counter is: " + i.ToString();
                        Thread.Sleep(1000);
                    }
                }));

    }));
t1.Start();

2 个答案:

答案 0 :(得分:6)

您的代码仅创建新线程以强制调度程序将您的操作同步回UI线程。我认为您添加了Dispatcher.BeginInvoke,因为从另一个线程更改mytxt1.Text会导致异常。试试这个:

Thread t1 = new Thread(new ThreadStart(
    delegate()
    {
        for (int i = 1; i < 11; i++)
        {        
            var counter = i; //for clouser it is important
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
                new Action(delegate()
                {                    
                    mytxt1.Text = "Counter is: " + counter.ToString();                                         
                }));
           Thread.Sleep(1000);
        }
    }

答案 1 :(得分:2)

设置文本的Action在UI上运行,这就是UI冻结的原因。

由于限制只有创建UI控件实例的线程(例如,UI线程)可以修改UI控件的属性,您必须运行在UI线程上设置文本的代码。这就是你正在做的事情。

您可以尝试的是让代码在Threading.Timer中运行。

或者......使用你已经拥有的代码,你应该有类似的东西,它可能会起作用:

Thread t1 = new Thread(new ThreadStart(
delegate()
{
    for (int i = 1; i < 11; i++)
    {
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        new Action(delegate()
            {                        
                    mytxt1.Text = "Counter is: " + i.ToString();                           

            }));
     Thread.Sleep(1000);
     }             
}));
t1.Start();