资源同步问题之防止界面假死
发布日期:2021-10-23 19:22:37 浏览次数:2 分类:技术文章

本文共 3025 字,大约阅读时间需要 10 分钟。

效果

代码

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。

转载于:https://www.cnblogs.com/beta2013/archive/2012/03/19/3377311.html

转载地址:https://blog.csdn.net/weixin_30624825/article/details/98914057 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:SpringMVC的工作流程-005
下一篇:【BZOJ 1051】 1051: [HAOI2006]受欢迎的牛 (SCC)

发表评论

最新留言

很好
[***.229.124.182]2024年04月17日 23时56分05秒