C#绝对新手之C#中的多线程小结

大概有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打交道:

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值