线程.更新主界面数据

ZC:(20191220)查到,“this.Dispatcher.Invoke(delegateSetText, new object[] { i.ToString() });” 是同步的,可以使用 BeginInvoke就可以不是同步的了。BeginInvoke 可能就和 MainWindow.FmainThreadContext.Post 类似了

ZC:注意:this.Dispatcher.Invoke 调用 非静态的函数 需要 DispatcherObject类型的对象实例来调用,例如:DispatcherObject.Dispatcher.Invoke(..., ...)。而 Post方式 需要 SynchronizationContext.Current 来调用(注意:子线程 执行SynchronizationContext.Current的话 返回的是 null ! ! !)

 

1、ZC:我的测试结论:

  (1)在拖动界面时 主界面 都会有卡顿400ms的现象,∵ 函数中"Thread.Sleep(400);"的缘故

  (2)主要区别:方式一、“this.Dispatcher.Invoke(...)”,子线程在执行过程中 同样会卡顿400ms

          方式二、“SynchronizationContext.Post(new SendOrPostCallback(???), obj);”,子线程 只是投递数据,不会卡顿

2、测试代码:

using System;
using System.Threading;
using System.Windows;

namespace Wpf_test01
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        static SynchronizationContext FmainThreadContext = null;

        public MainWindow()
        {
            InitializeComponent();

            FmainThreadContext = SynchronizationContext.Current;
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            delegateSetText = SetText;
            delegateSetText01 = SetText01;

            //Thread th = new Thread(ThreadSet);
            Thread th = new Thread(ThreadSet01);
            th.IsBackground = true;
            th.Start();
        }

        delegate void Delegate_SetText(string text);
        delegate void Delegate_SetText01(object obj);

        Delegate_SetText delegateSetText = null;// ZC: 在这里直接设置的话,需要是 静态的函数
        Delegate_SetText01 delegateSetText01 = null;

        void SetText(string text)
        {
            tb1.Text = text;
            Thread.Sleep(400);
        }

        void SetText01(object obj)
        {
            tb1.Text = (string)obj;
            Thread.Sleep(400);
        }

        void ThreadSet()
        {
            // ZC: 直接声明代理函数的方式
            //Delegate_SetText set = delegate(string text)
            //{
            //    tb1.Text = text;
            //};

            int i = 0;
            while (true)
            {
                Console.WriteLine("A : "+DateTime.Now.ToString(@"yyyyMMdd_HHmmss_fff"));
                this.Dispatcher.Invoke(delegateSetText, new object[] { i.ToString() });// ZC: WinForm的话 使用 this.Invoke(...)来调用
                Console.WriteLine("B : " + DateTime.Now.ToString(@"yyyyMMdd_HHmmss_fff"));
                Console.WriteLine();

                i++;
                Thread.Sleep(500);
            }
        }

        void ThreadSet01()
        {
            int i = 0;
            while (true)
            {
                Console.WriteLine("A : " + DateTime.Now.ToString(@"yyyyMMdd_HHmmss_fff"));
                MainWindow.FmainThreadContext.Post(new SendOrPostCallback(delegateSetText01), i.ToString());//通知主线程 // ZC: 个人感觉类似PostMessage(...)
                Console.WriteLine("B : " + DateTime.Now.ToString(@"yyyyMMdd_HHmmss_fff"));
                Console.WriteLine();

                i++;
                Thread.Sleep(500);
            }
        }

    }
}

 

 2.1、界面

  

 

 

 2.2、控制台输出:

  (1) this.Dispatcher.Invoke(...) 方式 

A : 20191031_094541_172
B : 20191031_094541_586

A : 20191031_094542_086
B : 20191031_094542_486

A : 20191031_094542_986
B : 20191031_094543_386

A : 20191031_094543_886
B : 20191031_094544_287

A : 20191031_094544_787
B : 20191031_094545_187

  (2) SynchronizationContext.Post(new SendOrPostCallback(???), obj); 的方式

A : 20191031_094750_654
B : 20191031_094750_666

A : 20191031_094751_166
B : 20191031_094751_166

A : 20191031_094751_666
B : 20191031_094751_666

A : 20191031_094752_166
B : 20191031_094752_166

A : 20191031_094752_666
B : 20191031_094752_666

 

3、

4、

5、

 

posted @ 2019-10-31 09:52  csskill  阅读(192)  评论(0编辑  收藏  举报