zoukankan      html  css  js  c++  java
  • 资源同步问题之防止界面假死

    效果



    代码下载



    代码

    using System;
    using System.Diagnostics;
    using System.Threading;
    using System.Windows.Forms;
    
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
    
            private void BtnBeginInvoke_Click(object sender, EventArgs e)
            {
                //接收指令后马上开一个新线程去执行后立即返回,防止界面假死  
                System.Threading.ThreadPool.QueueUserWorkItem(o => DoByBeginInvoke());
                Debug.WriteLine("BtnBeginInvoke_Click;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为9,表示UI线程的ID为9
            }
    
            void DoByBeginInvoke()
            {
                //模拟执行一个花费时间很长的业务  
                System.Threading.Thread.Sleep(5000);
                Debug.WriteLine("DoByBeginInvoke;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为10,表示当前代码未在UI线程上执行
    
                //专心更新界面  
                //此处的方法体依然在UI线程中完成执行,所以不要将其它非UI更新的操作放在里面,比如上面的模拟  
                LblCounter1.BeginInvoke(new Action(() =>
                {
                    LblCounter1.Text = (int.Parse(LblCounter1.Text) + 1).ToString();
                    Debug.WriteLine("LblCounter1.BeginInvoke;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为9,表示当前代码在UI线程上执行
                }));
                LblCounter2.BeginInvoke(new Action(() =>
                {
                    LblCounter2.Text = (int.Parse(LblCounter2.Text) + 1).ToString();
                    Debug.WriteLine("LblCounter2.BeginInvoke;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为9,表示当前代码在UI线程上执行
                }));
            }
    
    
            private void BtnSynchronizationContext_Click(object sender, EventArgs e)
            {
                //接收指令后马上开一个新线程去执行后立即返回,防止界面假死  
                System.Threading.ThreadPool.QueueUserWorkItem(DoBySynchronizationContext, System.Threading.SynchronizationContext.Current);
                Debug.WriteLine("BtnSynchronizationContext_Click;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为9,表示当前代码在UI线程上执行
            }
    
            void DoBySynchronizationContext(object state)
            {
                //模拟执行一个花费时间很长的业务  
                System.Threading.Thread.Sleep(5000);
                Debug.WriteLine("DoBySynchronizationContext;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为10,表示当前代码未在UI线程上执行
    
                var synchronizationContext=state as System.Threading.SynchronizationContext;
                synchronizationContext.Post(o =>
                {
                    //专心更新界面
                    //此处的方法体依然在UI线程中完成执行,所以不要将其它非UI更新的操作放在里面,比如上面的模拟  
                    LblCounter1.Text = (int.Parse(LblCounter1.Text) + 1).ToString();
                    LblCounter2.Text = (int.Parse(LblCounter2.Text) + 1).ToString();
                    Debug.WriteLine("synchronizationContext.Post;Thread ID:{0}", Thread.CurrentThread.ManagedThreadId);//输出为9,表示当前代码在UI线程上执行
                }, null);
            }
        }
    }
    


    备注

    线程执行时第一个控件被创建时,其SynchronizationContext.Current自动会被装上一个WindowFormsSynchronizationContext。

    WindowFormsSynchronizationContext对象内部创建了一个Control,用于提供Invoke和BeginInvoke来帮助实现SynchronizationContext的Send或Post。

  • 相关阅读:
    bzoj1455-罗马游戏
    bzoj1206-[HNOI2005]虚拟内存
    bzoj2762-[JLOI2011]不等式组
    bzoj2729-[HNOI2012]排队
    [模板] 高精度加/减/乘
    bzoj1013-[JSOI2008]球形空间产生器
    bzoj1002-[FJOI2007]轮状病毒
    什么是Redis缓存穿透、缓存雪崩和缓存击穿
    CentOS 7 中英文桌面安装步骤详细图解
    Redis数据操作
  • 原文地址:https://www.cnblogs.com/beta2013/p/3377311.html
Copyright © 2011-2022 走看看