最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#多線程之線程同步WaitHandle

 更新時間:2022年03月21日 10:33:30   作者:.NET開發(fā)菜鳥  
這篇文章介紹了C#多線程之線程同步WaitHandle的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、引言

在前面的文章中,我們是使用“鎖”的方式實現了線程間的通信,這種通信方式比較笨重。除了鎖之外,.NET中還提供了一些線程間更自由通訊的工具,他們提供了通過“信號”進行通訊的機制,通俗的比喻為“開門”、“關門”:Set()開門、Reset()關門、WaitOne()等著。

二、WaitHandle

WaitHandle位于System.Threading命名空間下,是用來封裝等待對共享資源進行獨占訪問的操作系統特定的對象。WaitHandle是一個抽象類,我們一般不直接使用,而是使用它的派生類:

  • AutoResetEvent。
  • EventWaitHandle。
  • ManualResetEvent。
  • Mutex。
  • Semaphore。

1、AutoResetEvent

AutoResetEvent表示線程同步事件在一個等待線程釋放后收到信號時自動重置。此類不能被繼承。

是一個自動阻塞,WaitOne()方法阻塞程序執(zhí)行,Set()方法釋放信息。當釋放后阻塞的代碼繼續(xù)執(zhí)行。但下一次執(zhí)行還需要等待信號。

通俗來說,WaitOne()是關門,Set()是開門。但開門之后,執(zhí)行完又自動關門,還需要開門。可以知道超時時間:

// 設置超時時間為2秒,如果2秒后沒有信號程序繼續(xù)執(zhí)行
are.WaitOne(2000);

看下面的一個例子:

using System;
using System.Threading;

namespace AutoResetEventDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 通過構造函數創(chuàng)建,默認是關門
            AutoResetEvent are = new AutoResetEvent(false);
            Thread t1 = new Thread(() => {
                while (true)
                {
                    Console.WriteLine("開始等著開門");
                    // 執(zhí)行完WaitOne之后自動關門
                    are.WaitOne();
                    Console.WriteLine("又關門了");
                }
            });
            // 啟動線程
            t1.Start();
            Console.WriteLine("按任意鍵開門");
            Console.ReadKey();
            //開門
            are.Set();

            Console.WriteLine("按任意鍵開門");
            Console.ReadKey();
            //開門
            are.Set();

            Console.WriteLine("按任意鍵開門");
            Console.ReadKey();
            //開門
            are.Set();

            Console.ReadKey();
        }
    }
}

程序輸出結果:

舉一個形象點的例子,AutoResetEvent相當于火車或者地鐵的閘機口,過了一個以后自動關門。

2、ManualResetEvent

Manual表示手動的??聪旅娴拇a:

using System;
using System.Threading;

namespace ManualResetEventDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 通過構造函數初始化
            // false表示“初始狀態(tài)為關門”,設置為true則表示初始狀態(tài)為開門
            ManualResetEvent mre = new ManualResetEvent(false);

            // 創(chuàng)建一個線程
            Thread t1 = new Thread(() => 
            {
                // 因為初始化的狀態(tài)為關門
                Console.WriteLine("開始等著開門");
                // 調用等著開門的方法,只有開門以后才會執(zhí)行下面的代碼
                mre.WaitOne();
                // 開門之后才會執(zhí)行這句代碼
                Console.WriteLine("終于開門了");
            });

            // 啟動線程
            t1.Start();

            Console.WriteLine("按任意鍵開門");
            Console.ReadLine();
            // 調用開門的方法
            mre.Set();

            Console.ReadKey();

        }
    }
}

運行程序,什么也不輸入,看一下輸出結果:

我們隨意輸入,再看運行結果:

怎么關門呢?關門也需要我們手動的調用:

using System;
using System.Threading;

namespace ManualResetEventDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 通過構造函數初始化
            // false表示“初始狀態(tài)為關門”,設置為true則表示初始狀態(tài)為開門
            ManualResetEvent mre = new ManualResetEvent(false);

            // 創(chuàng)建一個線程
            Thread t1 = new Thread(() => 
            {
                // 因為初始化的狀態(tài)為關門
                Console.WriteLine("開始等著開門");
                // 調用等著開門的方法,只有開門以后才會執(zhí)行下面的代碼
                mre.WaitOne();
                // 開門之后才會執(zhí)行這句代碼
                Console.WriteLine("終于開門了");
            });

            // 啟動線程
            t1.Start();

            Console.WriteLine("按任意鍵開門");
            Console.ReadLine();
            // 調用開門的方法
            mre.Set();
            // 休眠3秒
            Thread.Sleep(3000);
            // 關門
            mre.Reset();
            Console.WriteLine("關門了");

            Console.ReadKey();

        }
    }
}

程序輸出結果:

WaitOne()方法還可以設置等待超時時間,超過了等待時間就不會再等了。如果不設置等待超時時間,那么就會一直等下去。看下面代碼:

using System;
using System.Threading;

namespace ManualResetEventDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 通過構造函數初始化
            // false表示“初始狀態(tài)為關門”,設置為true則表示初始狀態(tài)為開門
            ManualResetEvent mre = new ManualResetEvent(false);

            //// 創(chuàng)建一個線程
            //Thread t1 = new Thread(() => 
            //{
            //    // 因為初始化的狀態(tài)為關門
            //    Console.WriteLine("開始等著開門");
            //    // 調用等著開門的方法,只有開門以后才會執(zhí)行下面的代碼
            //    mre.WaitOne();
            //    // 開門之后才會執(zhí)行這句代碼
            //    Console.WriteLine("終于開門了");
            //});

            // 創(chuàng)建一個線程
            Thread t1 = new Thread(() =>
            {
                // 因為初始化的狀態(tài)為關門
                Console.WriteLine("開始等著開門");
                // 設置超時等待時間為5秒鐘
                if(mre.WaitOne(5000))
                {
                    // 開門之后才會執(zhí)行這句代碼
                    Console.WriteLine("終于開門了");
                }
                else
                {
                    // 等待超時
                    Console.WriteLine("過了5秒鐘了還沒開門");
                }
                
            });

            // 啟動線程
            t1.Start();

            Console.WriteLine("按任意鍵開門");
            Console.ReadLine();
            // 調用開門的方法
            mre.Set();
            // 休眠3秒
            Thread.Sleep(3000);
            // 關門
            mre.Reset();
            Console.WriteLine("關門了");

            Console.ReadKey();

        }
    }
}

運行程序,什么也不輸入,看運行結果:

WaitHandle.WaitAll(WaitHandle[] waitHandles)用來等待所有信號都變?yōu)?ldquo;開門狀態(tài)”,WaitHandle.WaitAny(WaitHandle[] waitHandles) 用來等待任意一個信號都變?yōu)?ldquo;開門狀態(tài)”。

ManualResetEvent是一旦設定Set()后就一直開門,除非調用Reset()方法關門。

舉一個形象點的例子,ManualResetEvent就相當于是學校的大門,只要開門以后大家都可以進入,除非主動關門(等于執(zhí)行了Reset()方法)。

到此這篇關于C#多線程之線程同步WaitHandle的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 詳解C#對Dictionary內容的通用操作

    詳解C#對Dictionary內容的通用操作

    這篇文章主要為大家詳細介紹了C#對Dictionary內容的一些通用操作,例如:根據鍵移除信息、根據值移除信息、根據鍵獲取值等,需要的可以參考一下
    2022-06-06
  • C#異步調用實例小結

    C#異步調用實例小結

    這篇文章主要介紹了C#異步調用的方法,實例分析了C#同步調用及異步調用的常用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C# 實現Trim方法去除字符串前后的所有空格

    C# 實現Trim方法去除字符串前后的所有空格

    這篇文章主要介紹了C# 實現Trim方法去除字符串前后的所有空格,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • C#滾動字幕的實現方法

    C#滾動字幕的實現方法

    這篇文章主要介紹了C#滾動字幕的實現方法,主要講述了Graphics.DrawString函數的應用方法,非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • C# newtonsoft.json中文亂碼問號的解決方案

    C# newtonsoft.json中文亂碼問號的解決方案

    這篇文章主要介紹了C# newtonsoft.json中文亂碼問號的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C#實現將數據導出到word或者Excel中的方法

    C#實現將數據導出到word或者Excel中的方法

    這篇文章主要介紹了C#實現將數據導出到word或者Excel中的方法,涉及C#操作word及Excel格式文件的方法,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • C#標識符的使用小結

    C#標識符的使用小結

    C#標識符還是比較常見的東西,這里我們主要介紹C#標識符中的用法,包括介紹 static 的方法和bool 的形參等方面
    2014-01-01
  • C#?如何使用批處理啟動Windows服務

    C#?如何使用批處理啟動Windows服務

    這篇文章主要介紹了C#使用批處理啟動Windows服務,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • C# 多態(tài)性的深入理解

    C# 多態(tài)性的深入理解

    本篇文章是對C#中的多態(tài)性進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • C#Process的OutputDataReceived事件不觸發(fā)問題及解決

    C#Process的OutputDataReceived事件不觸發(fā)問題及解決

    這篇文章主要介紹了C#Process的OutputDataReceived事件不觸發(fā)問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論

达尔| 渝北区| 雷山县| 万宁市| 依兰县| 安吉县| 德昌县| 井陉县| 镇康县| 景德镇市| 彩票| 澄迈县| 南乐县| 兴海县| 曲水县| 海淀区| 来安县| 高邮市| 林甸县| 门头沟区| 旌德县| 丰镇市| 马尔康县| 松桃| 罗山县| 大理市| 屏东市| 梁河县| 宜章县| 夏津县| 吉林省| 连城县| 巴林右旗| 东辽县| 天镇县| 凤山县| 雷州市| 饶河县| 厦门市| 兴国县| 涡阳县|