对于上一节 番外篇之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);////委托的第一种使用方式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } } }
视频二:番外篇之委托-02委托的学习几大误区以及解决跨线程访问异常的方案
问题一:为什么使用委托以后,还会出现跨线程访问的错误.
误区:委托仅仅是将方法当做参数传递,“并不是用来执行或者解决一些特殊的问题,比如说跨线程异常”。
解决方案:使用Invoke关键字, this.Invoke(_GetInfo,new object []{hellow});
从创建窗口控件的线程上,用指定的参数列表执行指定委托
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } } }
视频三:03委托的注意事项以及多播委托
this.Invoke(); 推荐使用
原因:由于我的控件是”我”(Form1)创建的,那么最好还是由我来调用/销毁
在创建控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托 微软官方翻译
从创建控件的线程上,用指定的参数列表执行指定委托 君临翻译
Base.Invoke(); 越俎代庖.
在拥有控件的基础窗口句柄的线程上,用指定的参数列表执行指定委托。微软官方翻译
从拥有控件的线程上,用指定的参数列表执行指定委托
多播委托又被称为“委托链”
多播委托其实就是一个委托接一个委托……
执行所有给他注册的方法.
+= 增加一个委托方法
-= 去除一个委托方法.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } } }
视频教程出自:http://www.xuanjics.com/thread-79-1-1.html
玄机论坛的地址:www.xuanjics.com 原创作者:君临