来判断线程是否成功完成(回调的时 候线程应该已经完成了),二不需要他来传递数据,因为数据可以写在任何变量里,并且回调时应该已经填充,
所以可以看到微软在新的.Net Framework 中已经加强了对回调事件的支持,这总模型下,典型的回调程序应 该这样写 a.DoWork+=new SomeEventHandler(Caculate); a.CallBack+=new SomeEventHandler(callback); a.Run();
(注:我上面讲的是普遍的用法,然而 BeginXXX,EndXXX 仅仅是一种模式,而对这个模式的实现完 全取决于使用他的开发人员,具体实现的时候你可以使用另外一个线程来实现异步,也可能使用硬件的支 持来实现异步,甚至可能根本和异步没有关系(尽管几乎没有人会这样做)-----比如直接在 Beginxxx 里直 接输出一个"He
lloworld",如果是这种极端的情况,那么上面说的一切都是废话,所以上面的探讨并不涉及 内部实现,只是告诉大家微软的模式,和框架中对这个模式的经典实现)
异步和多线程有什么关联
有一句话总结的很好:多线程是实现异步的一种手段和工具 我们通常把多线程和异步等同起来,实际是一种误解,在实际实现的时候,异步有许多种实现方法,我 们可以用进程来做异步,或者使用纤程,或者硬件的一些特性,比如在实现异步 IO 的时候,可以有下面两 个
方案: 1)可以通过初始化一个子线程,然后在子线程里进行 IO,而让主线程顺利往下执行,当子线程执行完毕 就回调 2)也可以根本不使用新线程,而使用硬件的支持(现在许多硬件都有自己的处理器),来实现完全的异 步,这是我们只需要将 IO 请求告知硬件驱动程序,然后迅速返回,然后等着硬件 IO 就绪通知我们就可以 了 实际上 DotNet Framework 里面就有这样的例子, 当我们使用文件流的时候, 如果制定文件流属性为同步, 则使用 BeginRead 进行读取时,就是用一个子线程来调用同步的 Read 方法,而如果指定其为异步,则同样 操作时就使用了需要硬件和操作
系统支持的所谓 IOCP 的机制
WinForm 多线程编程篇
我的多线程 WinForm 程序老是抛出 InvalidOperationException , 怎么解决? 怎么解决?
在 WinForm 中使用多线程时,常常遇到一个问题,当在子线程(非 UI 线程)中修改一个控件的值:比 如修改进度条进度,时会抛出如下错误
Cross-thread operation not valid: Control 'XXX' accessed from a thread other than the thread it was created on. 在 VS2005 或者更高版本中,只要不是在控件的创建线程(一般就是指 UI 主线程)上访问控件的属性 就会抛出这个错误,解决方法就是利用控件提供的 Invoke 和 BeginInvoke 把调用封送回 UI 线程,也就是让 控件属性修改在 UI 线程上执行,下面列出会报错的代码和他的修改版本
ThreadStart threadStart=new ThreadStart(Calculate);//通过 ThreadStart 委托告诉子线程讲执行什么方法 Thread thread=new Thread(threadStart); thread.Start(); public void Calculate(){ double Diameter=0.5; double result=Diameter*Math.PI; CalcFinished(result);//计算完成需要在一个文本框里显示 } public void CalcFinished(double result){ this.TextBox1.Text=result.ToString();//会抛出错误
}
上面加粗的地方在 debug 的时候会报错,最直接的修改方法是修改 Calculate 这个方法如下
delegate void changeText(double result);
public void Calculate(){ double Diameter=0.5; double result=Diameter*Math.PI; this.BeginInvoke(new changeText(CalcFinished),t.Result);//计算完成需要在一个文本框里显示 }
这样就 ok 了,但是最漂亮的方法是不去修改 Calcu
late