zoukankan      html  css  js  c++  java
  • 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; }
            }
        }
    }

  • 相关阅读:
    Postman使用教程
    CAD和ArcGIS转换 矢量配准
    SAP CRM Advanced search和Simple search里Max hit表现行为的差异
    SAP CRM Product simple search的启用步骤
    如何快速定位SAP CRM订单应用(Order Application)错误消息抛出的准确位置
    如何动态修改SAP CRM WebClient UI表格栏的宽度
    如何在SAP CRM WebClient UI里创建web service并使用ABAP消费
    如何处理SAP CRM Web Service错误
    如何使用SAP CRM WebClient UI实现一个类似新浪微博的字数统计器
    如何开启SAP CRM基于WORD模板创建附件的功能
  • 原文地址:https://www.cnblogs.com/hackpig/p/1668361.html
Copyright © 2011-2022 走看看