• 番外篇 之 C#委托


     对于上一节 番外篇之C#多线程的反思 

          反思一:   Thread th = new Thread(参数); ////参数的总结

             ////首先,第一情况,对于 Thread th = new Thread(showLable);中的showLable()方法是无参的方法,则是调用了第二个重载的方法:public Thread(ThreadStart start);,无参数,直接创建实例。补充:public delegate void ThreadStart();

             private void showLable()
            {
                //labResult.Text = res.ToString();
            }
            private void btnGetName_Click(object sender, EventArgs e)
            {
                Thread th = new Thread(showLable);
                th.Start();
            }

           ////第二种情况,则是使用了第一种重载方法: public Thread(ParameterizedThreadStart start);先创建实例,在启动的时候,再传递参数,但是由于 thread.Start((object)strinfo);只有一个有参数的重载方法,而且只能是object类型,则直接导致了,GetInfo(object strinfo)传递参数类型只能是object类型。补充: public delegate void ParameterizedThreadStart(object obj);
            private void GetInfo(object strinfo)
            {
                MessageBox.Show(strinfo.ToString());
            }
            private void button1_Click(object sender, EventArgs e)
            {
                string strinfo = "Andrew";
                Thread thread = new Thread(GetInfo);
                thread.Start((object)strinfo);
            }

     反思二:Thread thread = new Thread(new ThreadStart(delegate { GetInfo((object)strinfo, strinfo); }));

                 关于匿名方法的使用:参考链接 http://www.cnblogs.com/Andrew2014/p/4074667.html

    视频一:委托的介绍以及委托的语法及其用法

               1. 委托是什么?

                   委托,委派一个人托付一件事。

                   是委托一个变量,一个方法(一件事)。

                   将方法当做参数传递

               2. 为什么要有委托?

                   实例:房子中介 

               3. 委托能干嘛呢?

               4.为什么委托跟指针一样?

                     委托和C++中的指针一样: 指针是指向内存地址;委托是“指向”方法的内存地址。

               5.委托的应用场景

                   在类中我需要传递给窗体一个信息,但是不想让这个信息以返回值的形式返回。

                          常规情况使用委托场景:

                         1.多线程中解决由“线程间操作无效:从不是创建控件“xxxx”的线程访问它。”

                         2.异步模式 (必须用委托,用事件也行)             

               6.多播委托

    this.Invoke(_GetInfo,new object []{hellow});

    额外的知识  this 关键字  

    标识当前活动的对象,如果在窗体中,那么可以表示当前的Form

    如果在事件中,表示当前激活事件的宿主。

     委托的语法

    权限修辞符  委托关键字  委托返回值   委托名([参数])

     public       delegate     void           GetInfo();////定义委托,相当于定义一个类。

    权限修辞符   委托            变量名

    public         GetInfo       getInfo;////声明委托变量,相当于声明一个类的实例。

    直接和方法调用一样,传递变量即可

    getInfo(str);////委托的第一种使用方式

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace _2014_11_05_01番外篇之委托
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void btnGetName_Click(object sender, EventArgs e)
            {
                Thread th = new Thread(new ThreadStart(delegate 
                    {
                        DelegateDemoClass ddcl = new DelegateDemoClass();
                        ddcl.getInfo = new GetInfo(showLable);////初始化委托变量
                        string name = txtName.Text;////跨线程异常,只针对给控件赋值,如果只是读取数据,不存在异常。
                        string hellow = ddcl.Hellow(name);
                        showLable(hellow);
                    }));
            }
    
            private void showLable(string res)
            {
                labResult.Text = res;////如何修复跨线程调用异常
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace _2014_11_05_01番外篇之委托
    {
        /// <summary>
        /// 无返回值,无参数委托
        /// </summary>
        public delegate void GetInfo(string res);////定义委托
    
        public class DelegateDemoClass
        {
            public GetInfo getInfo;////声明委托变量
            public string Hellow(string name)
            {
                string str = "Hellow " + name;
                getInfo(str);////委托的第一种使用方式,直接和方法调用一样,传递变量即可。
                return str;
                //return "Hellow "+name;
            }
        }
    }
    View Code

    视频二:番外篇之委托-02委托的学习几大误区以及解决跨线程访问异常的方案

    问题一:为什么使用委托以后,还会出现跨线程访问的错误.

    误区:委托仅仅是将方法当做参数传递,“并不是用来执行或者解决一些特殊的问题,比如说跨线程异常”。

    解决方案:使用Invoke关键字,  this.Invoke(_GetInfo,new object []{hellow});

                  从创建窗口控件的线程上,用指定的参数列表执行指定委托

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace _2014_11_05_01番外篇之委托
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            private void Form1_Load(object sender, EventArgs e)
            {
                _GetInfo = new GetInfo(showLable);
            }
    
    
            GetInfo _GetInfo;////在主窗体也声明一个委托的变量
    
            private void btnGetName_Click(object sender, EventArgs e)
            {
                Thread th = new Thread(new ThreadStart(delegate() 
                    {
                        DelegateDemoClass ddcl = new DelegateDemoClass();
                        ddcl.getInfo = new GetInfo(showLable);////正确的,直接初始化委托变量
                        //ddcl.getInfo = _GetInfo;////也是正确的,在内部声明委托,赋值给外部委托
                        string name = txtName.Text;////跨线程异常,只针对给控件赋值,如果只是读取数据,不存在异常。
                        string hellow = ddcl.Hellow(name);
                        //showLable(hellow);
                        //_GetInfo(hellow);
                        this.Invoke(_GetInfo,new object []{hellow});
                    }));
                th.Start();
            }
    
            private void showLable(string res)
            {
                labResult.Text = res;////如何修复跨线程调用异常
            }
    
         
        }
    }
    
    
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace _2014_11_05_01番外篇之委托
    {
        /// <summary>
        /// 无返回值,无参数委托
        /// </summary>
        public delegate void GetInfo(string res);////定义委托
    
        public class DelegateDemoClass
        {
            public GetInfo getInfo;////声明委托变量
            public string Hellow(string name)
            {
                string str = "Hellow " + name;
                //getInfo(str);////委托的第一种使用方式,直接和方法调用一样,传递变量即可。
                return str;
                //return "Hellow "+name;
            }
        }
    }
    View Code

    视频三:03委托的注意事项以及多播委托

    this.Invoke();   推荐使用

    原因:由于我的控件是”我”(Form1)创建的,那么最好还是由我来调用/销毁

    在创建控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托   微软官方翻译

    从创建控件的线程上,用指定的参数列表执行指定委托        君临翻译

     

    Base.Invoke();    越俎代庖.

    在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。微软官方翻译

    从拥有控件的线程上,用指定的参数列表执行指定委托 

     多播委托又被称为“委托链”

    多播委托其实就是一个委托接一个委托……

    执行所有给他注册的方法.

    +=  增加一个委托方法

    -=  去除一个委托方法.

    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 委托Demo
    {
    
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            GetInfo _GetInfo;//主窗体也声明这个委托的变量
            private void Form1_Load(object sender, EventArgs e)
            {
                // = 赋值
                _GetInfo = new GetInfo(showLable); 
               
                _GetInfo += new GetInfo(showLable1);   
                // += 注册方法
                _GetInfo += new GetInfo(showLable2);
            }
    
            private void btnGetName_Click(object sender, EventArgs e)
            {
                #region 基础的委托使用
                //Thread th = new Thread(new ThreadStart(delegate
                //{
                //    DelegateDemoClass ddcl = new DelegateDemoClass();
                //    //ddcl.getInfo = _GetInfo; 在内部声明委托,赋值给外部委托.
                //    ddcl.getInfo = new GetInfo(showLable);  //正确的.直接初始化委托
                //    string name = txtName.Text;
                //    string hellow = ddcl.Hellow(name);
                //    //_GetInfo(hellow); 
                //    //this.Invoke(ddcl.getInfo, new object[] { hellow });   等同于  this.Invoke(new Action<string>(showLable));
                //    //showLable(hellow);
                //}));
                //th.Start(); 
                #endregion
    
                _GetInfo -= new GetInfo(showLable1);   
                DelegateDemoClass ddcl = new DelegateDemoClass();
                string name = txtName.Text;
                string hellow = ddcl.Hellow(name);
                _GetInfo(hellow);
    
                //this.Invoke(ddcl.getInfo, new object[] { hellow });   等同于  this.Invoke(new Action<string>(showLable));
                //showLable(hellow); 
    
            }
            private void showLable2(string res)
            {
                MessageBox.Show(res + "showLable2");
            }
            private void showLable1(string res)
            {
                MessageBox.Show(res + "showLable1");
            }
            private void showLable(string res)
            {
                this.Invoke(new ThreadStart(delegate
                {
                    labResult.Text = res; //如何修复跨线程调用异常.
                }));
                //this.Invoke 是不可以使用lambda表达式. 
                //Thread th = new Thread(p => { 
    
                //});
                //ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { 
    
                //}));
                //ThreadPool.QueueUserWorkItem(p => { 
    
                //});
    
            }
        }
    }
    
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace 委托Demo
    {
        /// <summary>
        /// 无返回值,无参委托
        /// </summary>
        public delegate void GetInfo(string res); //声明委托
        public class DelegateDemoClass
        {
            public GetInfo getInfo; //声明委托变量
            public string Hellow(string name)
            {
                string str="Hellow " + name;
                //getInfo(str);//委托的第一种使用方式
                return str;
            }
    
        }
    }
    View Code

    视频教程出自:http://www.xuanjics.com/thread-79-1-1.html

                        玄机论坛的地址:www.xuanjics.com  原创作者:君临

                        QQ交流群:16885911  
  • 相关阅读:
    获取图片的大小(宽高):BytesIO
    python中url解析 or url的base64编码
    [extjs5学习笔记]第三十七节 Extjs6预览版都有神马新东西
    【翻译】Ext JS 6早期访问版本发布
    【翻译】Ext JS 6有什么新东西?
    【Java二十周年】Delphi转行java的一些小感触
    Cursor类取出数据
    通过服务修改widgetUI
    安卓笔记--Style的继承
    [ExtJS5学习笔记]第三十六节 报表组件mzPivotGrid
  • 原文地址:https://www.cnblogs.com/Time_1990/p/4071019.html
Copyright © 2020-2023  润新知