对WPF中数据的刷新机制感到迷惑,难道数据不是实时刷新显示的吗

对WPF中数据的刷新机制感到困惑,难道数据不是实时刷新显示的吗
情况一:针对一个TextBlock控件,不采用数据绑定,而是在C#代码中直接给TextBlock.Text赋值的情况

界面上有个Button,点击后执行如下代码,给TextBlock.Text赋值

private void Click_Button(object sender, RoutedEventArgs e)
{
    textBlock1.Text = "Running";

    //一段实现某功能的代码

    textBlock1.Text = "Complete";
}

问题来了:点击Button后,TextBlock根本不会显示”Running“字样,而是只显示”Complete“。单步调试后发现,在执行Click_Button事件的过程中,给TextBlock.Text赋值是不会刷新TextBlock的显示内容的,必须等整个Click_Button事件执行完了以后,TextBlock的内容才会刷新,所以只有末尾的textBlock1.Text = "Complete"这个语句表达出来了。

提问:怎么能实现TextBlock中内容的实时刷新?

情况二:使用数据绑定的情况

我自己写了一个叫Module的类,该类实现了INotifyPropertyChanged接口,有一个Num属性,会激发PropertyChanged事件。UI界面上有个TextBlock跟这个Num属性绑定。部分代码如下:

class Module : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
    private int num
    public int Num
    {
        get
        {
            return num;
        }
        set
        {
            num = value;
            if(this.PropertyChanged!=null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Num"));
            }
        }
    }
}

问题来了:同样用一个Button控件来执行一段代码,代码内容是把Num属性从1到100赋值100次,TextBlock的内容还是只显示一次100,而不是实时刷新显示从1到100的变化。

提问:数据绑定的情况下如何实现实时刷新?
------解决思路----------------------
1:使用System.Theading.Timer
2:使用for循环 赋值,每循环一次 使用Thead.Sleep(1000);休眠一次,你有必要了解一下Dispatcher对象。
------解决思路----------------------
想实时刷新,推荐你靠线程来解决,在额外的线程中处理业务逻辑,而把显示给Invoke到UI线程上来。
具体确实是要看Dispatcher。
------解决思路----------------------
不妨假设实现某功能的代码写成一个类

class 一段实现某功能的代码 
        {
            private Boolean 任务已完成=false ;

            public delegate void event_completed_handler(string message);
            public event event_completed_handler event_completed;

            public void do_任务已完成() 
            {
                if (event_completed != null) event_completed("任务已完成");
            }
            public void do_完成某功能()
           {
            /**
             *   
             *  if (任务已完成) do_任务已完成() ;
             * 
             */
            } 
           
        }
///////////////////////////////////
private void Click_Button(object sender, RoutedEventArgs e)
{
    textBlock1.Text = "Running";
 
    一段实现某功能的代码 obj=new 一段实现某功能的代码();
    obj.event_completed +=(s)=>{ ttextBlock1.Text = "Complete";};// 匿名函数写法
    obj.do_完成某功能();    
}