共 1,393 篇文章
共 6,621 篇文章及评论
- Association for Computing Machinery TechNews (ACM)
- Go Parallel! (Dr. Dobbs)
- HPCwire (Tabor Communications, Inc.)
- insideHPC (John West)
- Joe Duffy's Weblog (Microsoft)
- Microsoft Parallel Programming Development Center (Microsoft Germany)
- MultiCoreInfo.com
- scalability.org (Scalable Informatics)
- Software Dev Blog (Intel Germany)
- Soft Talk Blog (Intel United Kingdom)
- The Moth (Microsoft)
Archives
帖子来自 thy38 
C#绝对新手之 C#中的多线程小结
作者: thy38 (1 篇文章) 日期: 十一月 30, 2010 在 4:13 下午
评论 (0)
大概有4种方法: Dispatcher、异步委托、手动多线程、BackgroundWorker,另外还有一个DispatcherTimer,是定时器。 其中Dispatcher与DispatcherTimer相同,是利用在主线程进行任务优先级的排列来模拟多线程,因此其中实质是单线程,所以大负荷的运算不宜用它们。 BackgroundWorker会到线程池去抓一个线程作为工作线程,完成工作后切换回 UI 线程调用你定义的处理完成工作的委托。每计算出一次值,就会用worker.ReportProgress (percentComplete) 通知回调函数,并可在回调函数中更新UI。 特别适合需要更新已完成的百分比的场景。 这些都可以和数据绑定结合起来。 ①异步委托还是手动多线程 异步委托:支持线程结束时回调(BeginInvoke方法的的第一个参数),但不支持在外部中断线程,多用于更新UI。 手动线程:支持在外部中断线程(Thread.Abort方法),但不易得到函数的返回值。另外还不能更新UI。因为“Windows窗体”使用单线程单元 (STA) 模型(WPF窗体也一样),STA模型意味着可以在任何线程上创建窗口,但窗口一旦创建后就不能切换线程,并且对它的所有函数调用都必须在其创建线程上发生。特别是在注册事件的回调函数中要小心。 委托的用法: 这种调用方法和用委托对象的Invoke一样,都是同步调用,会阻塞当前线程。异步调用需要用BeginInvoke: 这里的BeginInvoke就是异步调用,运行后立即返回,不会引起当前线程的阻塞。但是在本例程中,因为newTask中要 Sleep 2秒中,如果Do Something else的时间没有2秒的话,EndInvoke还是会引起当前线程的阻塞,因为它要等待 newTask执行完毕。 那能不能不调用EndInvoke,让它自己结束呢?不太好。因为一来BeginInvoke和EndInvoke必须成对调用。即使不需要返 回值,但EndInvoke还是必须调用,否则可能会造成内存泄漏,因为它是利用了线程池资源。二来往往要调用EndInvoke 来获得函数的返回值。 如果是用BeginInvoke来进行轮询操作,EndInvoke是无法返回的,这时可以用一个变量来控制一下: 在我的应用场景里是定义了一个包装类: 要想完全与当前线程异步,可以利用BeginInvoke的第二个参数,设置一个函数执行完成后的回调函数: 这样就可以让当前线程完全没有等待的感觉了。 不过有时候,当前线程又想要利用函数执行的时间干点私活,然后在函数执行完成后再做别的,可以用WaitOne方法: (PS:用lambda语法还可以写出很炫的句子:) 其实还可以更直接: ) Invoke方法的主要功能就是帮助你在UI线程上调用委托所指定的方法。Invoke方法首先检查发出调用的线程(即当前线程 )是不是UI线程,如果是,直接执行委托指向的方法,如果不是,它将切换到UI线程,然后执行委托指向的方法。 手动线程的调用: 典型的写法是: 因为Thread调用的函数只能是无参数且无返回值的,因此通常要用类进行包装。 如果线程既需要可中断,又要与UI打交道:
