在winform开发,经常会遇到需要在控件上加载大量数据,这会导致程序出现假死状态,这个时候我们就会想到线程。
所有的 .NET Framework 应用程序都是使用单线程创建的,单线程用于执行该应用程序。在智能客户端应用程序中,这样的线程创建并管理用户界面 (UI),因而称为 UI 线程。
可以将 UI 线程用于所有的处理,其中包括 Web 服务调用、远程对象调用和数据库调用。然而,以这种方式使用 UI 线程通常并不是 一个好主意。在大多数情况下,您不能预测调用 Web 服务、远程对象或数据库会持续多久,而且在 UI 线程等待响应时,您可能会导致 UI 冻结。
通过创建附加线程,应用程序可以在不使用 UI 线程的情况下执行额外的处理。当应用程序调用 Web 服务时,可以使用多线程来防止 UI 冻结或并行执行某些本地任务,以整体提高应用程序的效率。在大多数情况下,您应该坚持在单独的线程上执行任何与 UI 无关的任务。
线程的异步调用不多说,我们这里说的是当获取了大量数据后需要返回UI 线程。在将数据绑定到控件上 这里可以先创建一个新线程(或者其他的异步方法)获取数据,当数据获取完后转入UI线程使用BeginInvoke()方法。
异步调用有:
1 . 委托异步调用。
2. 使用IAsyncResult接口实现异步调用
3. 基于事件的异步调用模式
4. 创建新线程的异步方式
5. 使用线程池的异步方式
6. 使用BackgroundWorker实现异步调用
1. 委托异步调用:由于它的实现是将原本需要阻塞的操作交给线程池的工作线程来处理了, 此时线程池的工作线程被阻塞了。因此,此方法对于依赖【线程池的工作线程】来处理任务的编程模型来说是没有意义的。 比如:Asp.net, Windows Services这类服务类的编程模型。但对于WinForm这样的单线程编程模型来说, 是比较方便的,尤其是还可以实现并行执行一些任务。
2. 使用IAsyncResult接口实现异步调用:它的实现是将原本需要阻塞的操作交给线程池的I/O完成线程来处理了, 而在.net中,还没有任何编程模型使用此类线程来执行处理任务,因此,适合于任何编程模型。 但并不是所有的API都支持此类接口,因此适用面有限,且使用较为复杂,尤其是某个过程需要多次异步调用时。 一般说来,许多I/O操作(文件I/O操作以及网络I/O)是支持此类API接口的。
3. 基于事件的异步调用模式:这种方式可以认为是一种封装模式,主要是为了简化线程模型以及简化调用方式,增强了API的易用性。 如果此模式用于对IAsyncResult接口(并非委托异步)实现包装,那么它具有第2种方法的所有优点。
4. 创建新线程的异步方式:这种方式有点特殊,主要和什么样的编程模型以及创建了多少线程有关。 对于服务类的编程模型来说,如果每次的请求处理都采用这种方式,显然会创建大量线程,反而损害性能。 反之,在其它情况下也是可以考虑的。
5. 使用线程池的异步方式:基本上与第1种相似,不适合一些服务类的编程模型,仅仅适用于与用户交互的桌面程序。
6. 使用BackgroundWorker的方式:其实也是在使用线程池的工作线程,因此最适用的领域与1,5相似,只是它在使用上更方便而已。