C#委托+回调详解

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

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

看例子学习

窗体里面就放一个textboxspa

先这样写线程

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";
        }
    }
}

结果3d

 

就这一句   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";
        }
    }
}

而后启动code

蹦了orm

一块儿动就退出

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

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;
        }
    }
}

仍是这样用

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

相关文章
相关标签/搜索