C# 多线程控制控件实例

简介:

该实例功能为“多线程控制UI控件”,线程函数实现自动加1。界面如下:

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace treadTest
{   
    //定义委托
    public delegate void ListBoxDelegate();
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //委托处理方法(关联与ListBoxDelegate)
        private void ListBox()
        {
            if (!listBox1.InvokeRequired)//如果在UI主线程操作ListBox,
            {
                listBox1.Items.Add(++CommonData.num);//则直接进行控件操作,“与UI主线程相关联”
                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
            }
            else//如果是在另一线程操作ListBox,则启用委托
                listBox1.Invoke(new ListBoxDelegate(listShow));
        }
       
        //定义对UI主线程控件的操作,“与AddAuto相关联”。
        private void listShow()
        {
            listBox1.Items.Add(CommonData.num);
            listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
        }
        //定义线程函数
        private void AddAuto()
        {
            while (CommonData.Flag == 0)
            {
                CommonData.num++;
                Thread.Sleep(1000);
                ListBox();//不能直接控制UI上的控件,所以用该方法选择使用委托
            }
        }
        //在click事件中启动多线程
        private void btnStart_Click(object sender, EventArgs e)
        {
            //线程标志置0,表示开启线程
            CommonData.Flag = 0;
            //定义 ThreadStart的委托类型的参数,并使该委托指向线程函数
            ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);
            //实例化线程
            Thread insertTxt = new Thread(new ThreadStart(mycn));
            //启动线程
            insertTxt.Start();     
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            CommonData.Flag = 1;
        }
        private void btnCtrlMain_Click(object sender, EventArgs e)
        {
            ListBox();
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            CommonData.num = 0;
        }
        private void btnClear_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }
        private void btnQuit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }


    }
   
    //全局变量解决方案
    public class CommonData
    {
        private static int _Flag = 0;
        private static int _num = 0;
        public static int Flag
        {
            get { return _Flag; }
            set { _Flag = value; }
        }
        public static int num
        {
            get { return _num; }
            set { _num = value; }
        }
    }
}

总结:

        要使用多线程控制UI控件,必须用委托实现。调用控件的Invoke方法(Invoke方法的参数是一个委托类型的参数)。

实现步骤:

         1.声明委托。

          2.声明委托处理函数(判断是主线程控制UI控件,还是Invoke(多线程)控制UI控件)。

         3.声明一个线程实例,将线程函数的委托传入ThreadStart()。

         4.开启该线程。

         5.定义该线程函数,欲控制UI控件,则调用第2步的委托处理函数,他将自己判断选择用Invoke。

         6.定义Invoke需要调用的函数(如本例的listShow函数)

//*********************************************************************************************************************************

      在上例中,只是完成了多线程控制主线程控件的功能,如果能手动和自动同时访问全局变量时,就有可能出现线程不同步的问题。以下主要利用lock线程锁来修改解决方案,使线程同步,注意代码带动的地方。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace treadTest
{   
    //定义委托
    public delegate void ListBoxDelegate();
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //委托处理方法(关联与ListBoxDelegate)
        private void ListBox()
        {
            if (!listBox1.InvokeRequired)//如果在UI主线程操作ListBox,
            {
                listBox1.Items.Add(CommonData.plus());//则直接进行控件操作,“与UI主线程相关联”
                listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
            }
            else//如果是在另一线程操作ListBox,则启用委托
                listBox1.Invoke(new ListBoxDelegate(listShow));
        }
       
        //定义对UI主线程控件的操作,“与AddAuto相关联”。
        private void listShow()
        {
            listBox1.Items.Add(CommonData.plus());
            listBox1.SelectedItem = listBox1.Items[listBox1.Items.Count - 1];
        }
        //定义线程函数
        private void AddAuto()
        {
            while (CommonData.Flag == 0)
            {
                Thread.Sleep(1000);
                ListBox();//不能直接控制UI上的控件,所以用该方法选择使用委托
            }
        }
        //在click事件中启动多线程
        private void btnStart_Click(object sender, EventArgs e)
        {
            //线程标志置0,表示开启线程
            CommonData.Flag = 0;
            //定义 ThreadStart的委托类型的参数,并使该委托指向线程函数
            ListBoxDelegate mycn = new ListBoxDelegate(AddAuto);
            //实例化线程
            Thread insertTxt = new Thread(new ThreadStart(mycn));
            //启动线程
            insertTxt.Start();     
        }

        private void btnAbort_Click(object sender, EventArgs e)
        {
            CommonData.Flag = 1;
        }
        private void btnCtrlMain_Click(object sender, EventArgs e)
        {
            ListBox();
        }
        private void btnReset_Click(object sender, EventArgs e)
        {
            CommonData.num = 0;
        }
        private void btnClear_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        }
        private void btnQuit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
   
    //全局变量解决方案
    public class CommonData
    {
        private static int _Flag = 0;
        private static int _num = 0;
        public static int plus()
        {
            lock (new object())
            {
                return _num++;
            }
        }
        public static int Flag
        {
            get { return _Flag; }
            set { _Flag = value; }
        }
        public static int num
        {
            get { return _num; }
            set { _num = value; }
        }
    }
}




本文转自黄聪博客园博客,原文链接:http://www.cnblogs.com/huangcong/archive/2010/03/26/1697090.html,如需转载请自行联系原作者

相关文章
|
1月前
|
SQL 开发框架 .NET
C#一分钟浅谈:数据绑定与数据源控件
在Web开发中,数据绑定和数据源控件是实现动态网页的关键技术。本文从基础概念入手,详细讲解数据绑定的原理及其在ASP.NET中的应用,并介绍常见数据绑定方式:手动绑定和自动绑定。接着,文章重点介绍了ASP.NET中的数据源控件,如`SqlDataSource`、`ObjectDataSource`、`XmlDataSource`和`LinqDataSource`,并通过具体示例演示如何使用`SqlDataSource`和`GridView`进行数据绑定。最后,还列举了一些常见问题及其解决办法,帮助读者更好地理解和应用这些技术。
65 4
|
3月前
|
数据采集 XML JavaScript
C# 中 ScrapySharp 的多线程下载策略
C# 中 ScrapySharp 的多线程下载策略
|
3月前
|
C#
|
25天前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
1月前
|
数据可视化 程序员 C#
C#中windows应用窗体程序的输入输出方法实例
C#中windows应用窗体程序的输入输出方法实例
46 0
|
2月前
|
安全 数据库连接 API
C#一分钟浅谈:多线程编程入门
在现代软件开发中,多线程编程对于提升程序响应性和执行效率至关重要。本文从基础概念入手,详细探讨了C#中的多线程技术,包括线程创建、管理及常见问题的解决策略,如线程安全、死锁和资源泄露等,并通过具体示例帮助读者理解和应用这些技巧,适合初学者快速掌握C#多线程编程。
81 0
|
3月前
|
安全 C# 开发者
【C# 多线程编程陷阱揭秘】:小心!那些让你的程序瞬间崩溃的多线程数据同步异常问题,看完这篇你就能轻松应对!
【8月更文挑战第18天】多线程编程对现代软件开发至关重要,特别是在追求高性能和响应性方面。然而,它也带来了数据同步异常等挑战。本文通过一个简单的计数器示例展示了当多个线程无序地访问共享资源时可能出现的问题,并介绍了如何使用 `lock` 语句来确保线程安全。此外,还提到了其他同步工具如 `Monitor` 和 `Semaphore`,帮助开发者实现更高效的数据同步策略,以达到既保证数据一致性又维持良好性能的目标。
49 0
|
3月前
|
传感器 开发框架 JSON
聊聊 C# dynamic 类型,并分享一个将 dynamic 类型变量转为其它类型的技巧和实例
聊聊 C# dynamic 类型,并分享一个将 dynamic 类型变量转为其它类型的技巧和实例
160 0
|
6月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
201 3