• C#委托+回调详解


    今天写不完,明天会接着写的,,,,

    学习C#有一段时间了,不过C#的委托+回调才这两天才会用,以前只是知道怎么用.前面的一篇文章,函数指针,其实是为这个做铺垫的,说白了委托就相当于C语言中的函数指针,具体说用委托有什么好处,我也不知道,但是因为你只要学C#那么回调就一定要会,回调是委托的一种.回调多用于线程间....还是用代码一点点的说明吧!现在认为自己以前不会用委托是因为手太懒,再者没有太多的必须用C#做的Demo,自己学东西都是用到什么学什么,想做什么东西需要什么知识就学什么,前几天有了必须要做的C#的Demo,关于检测TCP通信发过来的数据的.扯了这么多...回调主要的应用是---如果你在一个线程里操作像文本框,按钮,Label等组件时,会报错...原因--C#它不让这样操作,,,,

    看例子

    窗体里面就放一个textbox

    先这样写

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                textBox1.Text = "123456";
            }
        }
    }

    结果

    就这一句   textBox1.Text = "123456";往文本框中写入123456     程序运行没问题

    现在加入线程

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                writeThread = new Thread(write_Metod);
                writeThread.Start();
            }
            private void write_Metod()
            {
                textBox1.Text = "123456";
            }
        }
    }

    然后启动

    蹦了

    一起动就退出

     说早了.......先说委托

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                write_Metod();
            }
            private void write_Metod()
            {
                textBox1.Text = "123456";                      
            }
        }
    }

    这个是没有用委托的,简单的例子,程序一运行就执行write_Metod();函数然后文本就打印123456了

    现在就用委托来写一下

     函数名字太长会让人感觉特复杂有木有....所以下面的名字.....

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            delegate void a();//定义一个委托111111111111111111
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                a b= new a(c);//实例化2222222222222222222
                b();//3333333333333333333333
            }
            void c()
            {
                textBox1.Text = "123456";                      
            }
        }
    }

     delegate void a();//定义一个委托111111111111111111
    这是定义一个委托 要用关键字 delegate
    后面的

    void a();
    函数名字自己取,,不过要有自己的规范,,有自己的一套编程风格就好..
    void a();
    这是一个没有返回值的,无参数的函数
    因为学过函数指针都知道,只有类型一样的函数才能把一个函数的指针(地址)传给另一个函数..
    因为我们希望把
    void c()这个函数用另一个函数代替
    这个函数的类型是void 的 无参数的函数

    所以就这样定义了
    delegate void a();//定义一个委托----再次说明delegate是关键字,意味着定义了一个委托------你说函数指针也行,,C#啊;;;淡化了指针的概念

    然后
    a b= new a(c);//实例化2222222222222222222

    不知道有没有不知道为何实例化的
    如果不知道实例化那么知道对象吗?是C#整的名词对象
    如果不知道对象那么知道类吗?,,,,,
    上面所说的没有什么用的,只是用来吓唬人的,记得第一次想学高级语言,,,一打开书,,,,,崩溃了,彻底崩溃了,什么对象,,,,一开头介绍就是,,,什么面向对象,,吓的我赶紧把书方回去,,心有不甘再来一本,,没想到一打开书...又来了,,,XXXXXX是面向对象的语言,,,,,那时候在想,我去太高深了,,面向对象,,面对谁呢!! 毕向东的JAVA讲的不错....学会一门高级语言,语言有很多共通的地方
    又耽误大家时间了....对了马士兵的JAVA也挺好,,,都看看 都看看
    关于实例化
    定义一个A a;假设定义了一个a
    如果你不实例化也就是 a = new A();
    那么系统不会为a开辟任何空间,只有 a = new A();了 系统才会在内存中为 a 开辟一段空间,才真正有了a的存在


    a b= new a(c);//实例化2222222222222222222
    这一句的意思就是
    b= c;
    哦,原来就是函数指针赋值啊
    那么
    b();   就相当于  c();
    好再过一遍
    先定义一个委托
    delegate void a();//定义一个委托

    然后实例化---a b = new a(c);
    void c()
    {

    }
    这样 b 就==c了
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            delegate void a();//定义一个委托
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                a b = new a(c);//实例化
                b();
            }
            void c()
            {
                textBox1.Text = "123456";                      
            }
        }
    }


    咱接着

    假如说

     void c(string str)
            {
                textBox1.Text = str;                      
            }

    那么我定义的委托(函数指针)也应该是

    delegate void a(string str);//定义一个委托

    怎样把c传过去呢

    a b = new a(c);//实例化

    然后

    b("123456");

    因为c是

    void c(string str)
    所以
    必须写个string进去嘛
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            delegate void a(string str);//定义一个委托
            
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                a b = new a(c);//实例化
                b("123456");
            }
            void c(string str)
            {
                textBox1.Text = str;                      
            }
        }
    }


    委托也就这样吧
    下面看 回调

    窗体不变

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                writeThread = new Thread(c);
                writeThread.Start();
            }
            private void c()
            {
                textBox1.Text = "123456";
            }
        }
    }

    然后启动

    程序---崩了

    好现在

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;////////**************************加了这一句
                writeThread = new Thread(c);
                writeThread.Start();
            }
            private void c()
            {
                textBox1.Text = "123456";
            }
        }
    }

    满血复活了..

    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
    上一次程序崩掉是因为C#不让跨线程调用窗体控件--不让在一个新的线程里
    调用窗体控件---
    textBox1.Text = "123456";就是在使用窗体控件textbox
    加上这句System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls
    Check  For  Illegal  Cross  Thread  Calls  == false;   不检查
    检查 对 非法的 交叉 线程 调用
    所以就通过了---当自己写程序时调试可以使用,,真正做项目嘛,,,,,因人而异吧

    C#提供了几种种方法来让我们在线程里来操作窗体控件---其它高级语言也提供了相应的方法的
    看 回调 来也

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            delegate void a();//定义回调
            a b;//声明回调
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                b = new a(d);//实例化回调
    
                writeThread = new Thread(c);
                writeThread.Start();//启动C线程
            }
            private void c()
            {
                textBox1.Invoke(b);
            }
            private void d()
            {
                textBox1.Text = "123456";
            }
        }
    }
    textBox1.Invoke(b);
    其实就多了这一句
    还可以这样
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            delegate void a(string str);
            a b;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                b = new a(d);
    
                writeThread = new Thread(c);
                writeThread.Start();
            }
            private void c()
            {
                textBox1.Invoke(b,"123456");
            }
            private void d(string str)
            {
                textBox1.Text = str;
            }
        }
    }
    textBox1.Invoke(b,可以带参数);//这是固定形式,就是这样用,,,人家规定的
    现在放一个按钮

    一启动

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace @delegate
    {
        public partial class Form1 : Form
        {
            Thread writeThread;
            delegate void a(string str);
            a b;
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                b = new a(d);
    
                writeThread = new Thread(c);
                writeThread.Start();
            }
            private void c()
            {
                button1.Invoke(b, "123456");
            }
            private void d(string str)
            {
                button1.Text = str;
            }
        }
    }

    还是这样用

    就写这些吧!简简单单普普通通,,,现在博客园终于能复制粘贴图片了........太方便了

  • 相关阅读:
    jqueryeasyui 使用笔记
    怎么查看端口占用情况?
    Ie6 Ie7 双倍padding
    Javascript获取URL
    fckeditor,用p替代div标签设置对齐方式
    ZenCart安全建站的几个措施和步骤
    复选框二选一 javascript
    dedecms从php设置里面去掉index.html
    ajax调用webservice返回DataTable "序列化类型为“System.Reflection.Module”的对象时检测到循环引用
    无题
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/5761841.html
Copyright © 2020-2023  润新知