zoukankan      html  css  js  c++  java
  • C#粗谈线程处理对象和功能

          最近在学习线程同步的一些东西,发现这里面的水很深,边看MSDN边查各种博客边写Demo,却只是略懂皮毛,先做一下记录,以后慢慢补充,先给出一些网站,关于线程对象的资料:

         1. (MSDN)线程处理对象列表   这里面有ThreadPool、BackgroundWorker、Monitor、WaitHandle、EventWaitHandle、AutoRetsetEvent、ManualResetEvent、Mutex等线程处理对象的介绍,每个连接点开,就是每个对象的详细解释,然后再详细解释页面再点开就是每个对象的属性、时间、方法、示例等,很详细。

         2. 写个自己的博客之线程同步系列博客五篇  这是其他人对这些东西的领悟,比我要深很多,记录。

         3. (CSDN)码农时代的线程同步博客

        我对这几个对象理解很浅,大家可以看下,然后再看上面这几个,便于理解,顺便有什么说的不对的地方,可以帮忙批评指正一下。

    第一个,ThreadPool:

        线程池ThreadPool:主要用到的方法就是QueueUserWorkItem(WaitCallback, Object), 它把一个工作线程放进队列中,进行排队以便于进行执行。

        关于ThreadPool的详细信息,查看这里ThreadPool

    第二个, BackgroundWorker:

        前几天刚写了一篇关于这个组件的用法,点击这里.

    第三个, Monitor:

        监视器Monitor主要有以下几个方法:Enter、Exit、TryEnter、Wait、Pulse、PulseAll,解释如下:

        Monitor 对象通过使用 Monitor.Enter  Monitor.TryEnterMonitor.Exit 方法对特定对象进行加锁和解锁来提供同步访问代码区域的功能。 对代码区域加  锁之后,可以使用 Monitor.WaitMonitor.PulseMonitor.PulseAll 方法。 Wait 在其暂停并等待通知的情况下解锁。 Wait 收到通知时,会返回并重新加锁。 PulsePulseAll 都发送信号以继续执行等待队列中的下一个线程。

    其中,Monitor的Enter方法和Exit方法是成对出现,调用了多少次Enter就要调用多少次Exit,不然会出现异常。且,

    Monitor.Enter();
    try
    {
         //
    }
    Finally
    {
         Monitor.Exit();
    }
    
    等价于:
    
    private static ReadOnly object syncObj = new object();
    
    lock(syncObj)
    {
         //
    }

                              **¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**¥**

    对于WaitHandle、EventWaitHandle、AutoRetsetEvent、ManualResetEvent、Mutex用家族树的方法来看就是: WaitHandle是爷爷辈的一棵独苗,然后生了两个孩子EventWaitHandle和Mutex, 然后Mutex打了光棍,EventWaitHandle生了两个孩子AutoRetsetEvent和ManualResetEvent。

    祖辈,WaitHandle:

    线程可以通过调用实例方法 WaitOne 在单个等待句柄上阻塞。 此外,WaitHandle 类重载了静态方法,以等待所有指定的等待句柄集都已收到信号 (WaitAll),或等待某一指定的等待句柄集收到信号 (WaitAny)。 这些方法的重载提供了放弃等待的超时间隔、在进入等待之前退出同步上下文的机会,并允许其他线程使用同步上下文。

    在 .NET Framework 2.0 版中,等待句柄还具有静态 SignalAndWait 方法,它允许线程发送一个等待句柄信号并立即等待另一个。(MSDN中原话,我没这么牛逼)

    这里主要讲一下SignalAndWait(WaitHandle, WaitHandle):MSND对它的解释是向一个 WaitHandle 发出信号并等待另一个。 这个把我晕了很久,后来多次测试分析发现就是:

            WaitHandle ewh = null;
            long threadCount;
            WaitHandle countClear = new EventWaitHandle(false, EventResetMode.AutoReset);
    
            private void DoThreadsTask()
            {
                ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
                Thread t = new Thread(ExcuteThreadTask);
                t.Start(1);
                while (Interlocked.Read(ref threadCount) < 1)
                {
                    Thread.Sleep(1000);
                }
    
                while (Interlocked.Read(ref threadCount) > 0)
                {
                    Trace.WriteLine("Release a waiting thread.");
                    WaitHandle.SignalAndWait(ewh, countClear);
                }
                Trace.WriteLine("Press ENTER to release the waiting threads.");
            }
    
            private void ExcuteThreadTask(object obj)
            {
                int index = (int)obj;
                Trace.WriteLine(string.Format("Thread {0} blocks.", index));
                Interlocked.Increment(ref threadCount);
                Trace.WriteLine("1当前值为:" + threadCount);
                ewh.WaitOne();
                Trace.WriteLine(string.Format("Thread {0} exits.", index));
                Interlocked.Decrement(ref threadCount);
                Trace.WriteLine("2当前值为:" + threadCount);
                countClear.Set();
            }
    
           public delegate void StartThreadsHandler();
            private void btnStart_Click(object sender, EventArgs e)
            {
                StartThreadsHandler handler = DoThreadsTask;
                handler.BeginInvoke(null, null);
            }

    简单来说就是:两个WaitHandle的实例A、B,A在工作线程调用了A.WaitOne(), B没有做任何操作,然后调用静态方法WaitHandle.SignalAndWait(A, B)等价于:A.Set();

    B.WaitOne();两个方法。

    父辈之光棍,Mutex:

           主要用法可以控制应用程序只开启一个,当前不关闭,无法再打开另外一个,参考这里

    父辈EventWaitHandle和孙辈AutoResetEvent、ManualResetEvent:

    AutoResetEvent的功能等价于 EventWaitHandle(false, EventResetMode.AutoReset), 而ManualResetEvent的功能等价于 EventWaitHandle(false, EventResetMode.ManualReset) 。

    MSDN中的说法:

    EventWaitHandle 类可以表示自动或手动重置事件以及本地事件或命名系统事件。

    AutoResetEvent 类派生自 EventWaitHandle,表示自动重置的本地事件。

    ManualResetEvent 类派生自 EventWaitHandle,表示必须手动重置的本地事件。

    对于孙子辈的这两个对象的执行过程,我的理解是:打个比方,在羊圈中有10头羊(10个工作线程),如果羊圈门AutoResetEvent ARE, ARE = new AutoResetEvent(false)表示羊圈门是关着的,调用ARE.Set()表示门打开,一只羊出来(工作线程被阻塞结束,可以继续执行),然后门自动关闭(ARE.Reset()),调用调用ARE.Set()表示门打开,第二只羊出来... AutoResetEvent(true)表示羊圈门是开着的,即使调用ARE.WaitOne(),门依旧开着,出来一只羊,门自动关闭,需要调用ARE.Set()打开门....   如果羊圈门ManualResetEvent MRE,MRE = new ManualResetEvent(true)表示门是打开着的,第一只羊出来,接着第二只,如果不调用MRE.Reset()则门一直开着,不会自动关闭,反之,MRE = new ManualResetEvent(false)表示门是关着的,调用MRE.Set()则门一直打开,除非手动调用MRE.Reset().....例子就不写了,参考MSDN吧。

  • 相关阅读:
    在代码里面和在manifest里面配置去标头;
    textview实现跑马灯的效果
    下载完apk安装包后实现自动安装;
    xlistview刷新加载
    handler结合子线程实现pulltorefresh刷新加载;
    百度定位,发起定位
    商品条形码(JBarcode)Java版(二)
    商品条形码(JBarcode)
    Intellij IDEA 鼠标悬浮放上去提示参数
    MySQL 正则表达式,部分不同于Java或者JS正则
  • 原文地址:https://www.cnblogs.com/yuqf/p/3096548.html
Copyright © 2011-2022 走看看