C#多线程整理(一)

一、为什么要使用多线程?
1、提升系统的吞吐量,也即效率(大多数课本上都会这样讲,我也认为确实可以,但实际中应用较少使用到)
2、使UI保持响应;
3、在整合系统中,一个系统在运行中等待另一个系统执行结果的返回;(其实也是保持响应)

二、使用线程的难点:
1、线程控制(也即调度,这个基本上我们控制不了,操作系统有自己的调度策略)
2、线程间通信(线程同步)
3、临界资源问题(也即线程互斥,其实如何发现临界资源也是一个话题,不是吗?)

三、C#中开启多线程的方法:
1、UI控件中的BeginInvoke方法

这个方法可以在不阻塞UI的情况下(即UI可以正常响应用户的操作),指定委托指向的特定方法。

通常来将调用这个方法,一般是下面两种情况:

(1)在保持ui用户响应的前提下,去执行一个非常耗时的方法;

(2)在非UI线程执行中,想要报执行结果显示在UI中,这时可以使用这个方法,来达到切换线程的目的

2、委托的BeginInvoke方法

这个是一个比较好理解的逻辑结构实现的一种多线程方法;

实现步骤:

(1)定义开启多线程的委托,即准备要进行BeginInvoke的;(主要是针对要调用的耗时的外部方法的签名进行定义)

如:delegate string WSTestMethodHandler();

(2)定义线程切换使用的委托;(这个主要作用是:在多线程执行完毕后,回调函数中,将非UI线程转换为UI线程)。

如:delegate void AsyncCallerSwitcher(IAsyncResult a);

(3)定义具体的耗时方法

如:string TestMethod();

(4)定义具体的回调函数(这里有个小trick(戏法,把戏,技巧),就是这个函数同时作为回调,和切换线程的之用,也即对于回调函数和切换线程的函数我们可以只定义一个函数,之所以这样,是因为这两个方法接口是可以统一的。当然这里需要使用到InvokeRequired属性,以确定是否可以直接对UI进行操作)

如:void TestMethodCallBackMethod(IAsyncResult a)

(5)定义开启多线程委托的实例,即将委托指向具体的某个方法,即将(3)步中的方法名作为参数,传递给(1)步定义的委托,产生一个委托实例;

如:WSTestMethodHandler tmpAsyncCaller = new WSTestMethodHandler(TestMethod);

(6)定义回调函数的委托实例,即AsyncCallback系统委托的实例,这个委托的参数为IAsyncResult接口类型;

如:AsyncCallback tmpCallBacker = new AsyncCallback(TestMethodCallBackMethod);


3、Thread类
4、使用BackgoundWorker组件
5、使用System.Threading.ThreadPool.QueueUserWorkItem方法

四、在实践中发现真谛:
1、一个用多线程保持UI响应的例子;
2、一个用多线程整合WS的例子;

线程有诸多好处,这是大家有目共睹的了,但是它的难以控制也是大家痛心疾首的问题,
线程控制的几个方式:
1、回调函数
2、AutoResetEvent,ManualResetEvent
3、其实线程对象自身也包含有同步方法,这个要研究一下;

 

/*
         * AutoResetEvent和ManualResetEvent区别:
         * AutoResetEvent会在每次调用完WaitOne方法后,自动设置AutoResetEvent对象为阻止状态
         *      即在成功通过WaitOne后,再次调用WaitOne时会阻塞
         * ManualResetEvent在通过WaitOne方法后,再次调用WaitOne时不会阻塞,需要手动调用Reset方法
         */

 

/*
             *初始值不同,带来的不同执行行为
             *AutoResetEvent初始值为false    
             *这个会导致在第一调用WaitOne方法时就被阻塞
AutoResetEventThread thread will sleep 2000 seconds
AutoResetEventThread running at 2012-10-23 10:58:34.759
Main thread running at 2012-10-23 10:58:36.793           
             * AutoResetEvent初始值为true
             * 这个会导致第一次调用WaitOne方法时候不会被阻塞
             * 在下面的时间可以看出Main thread(2012-10-23 11:00:46.533)是先于AutoResetEventThread(2012-10-23 11:00:46.558)执行
AutoResetEventThread thread will sleep 2000 seconds
AutoResetEventThread running at 2012-10-23 11:00:46.558
Main thread running at 2012-10-23 11:00:46.533
             */

 

//使用此方法确保线程已终止。如果线程不终止,则调用方将无限期阻塞。
            //如果调用 Join 时该线程已终止,此方法将立即返回。
            //此方法更改调用线程的状态以包括 ThreadState.WaitSleepJoin。
            //对处于 ThreadState.Unstarted 状态的线程不能调用 Join
            //ThreadStateException  调用方尝试联接一个处于 ThreadState.Unstarted 状态的线程。
            //ThreadInterruptedException    此线程在等待时被中断。

 

待完善!!!!

 

示例代码:http://download.csdn.net/detail/jzt_designer/4697481

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值