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

詳解C# 線程的掛起與喚醒

 更新時(shí)間:2021年05月07日 08:39:48   作者:jack_Meng  
這篇文章主要介紹了詳解C# 線程的掛起與喚醒,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下

     如果說(shuō)C#和C++有什么不同,博主不得不說(shuō),對(duì)于異步的支持程度是C#的一一個(gè)偉大的進(jìn)步。

    其實(shí)早期的C++都沒(méi)有異步,并發(fā)的概念。博主第一次使用C++創(chuàng)建異步程序的時(shí)候,是使用boost庫(kù)的內(nèi)容進(jìn)行實(shí)現(xiàn)的。相對(duì)而言,C#對(duì)于異步的支持可以說(shuō)是相當(dāng)?shù)暮?。相信很多名詞大家都很耳熟能詳,比如說(shuō)Thread,BeginInvoke,Delegate,backgroundworker等等。。。其實(shí)樓主在使用了這么多的異步操作過(guò)程中,還是覺(jué)得backgroudworker比較好用。

    當(dāng)然,我們今天要說(shuō)的和上面的無(wú)關(guān)。講述的是如何在線程中進(jìn)行掛起喚醒操作。

    假設(shè),有一個(gè)Thread現(xiàn)在需要掛起,等到合適的時(shí)候再喚醒那么這個(gè)線程(消費(fèi)者模式)。如果大家需要用Suspend,Resume操作,我建議還是要思考再三。以下是msdn原話(https://msdn.microsoft.com/zh-cn/library/system.threading.thread.suspend(v=vs.110).aspx):

    Do not use the Suspend and Resume methods to synchronize the activities of threads. You have no way of knowing what code a thread is executing when you suspend it. If you suspend a thread while it holds locks during a security permission evaluation, other threads in the AppDomain might be blocked. If you suspend a thread while it is executing a class constructor, other threads in the AppDomain that attempt to use that class are blocked. Deadlocks can occur very easily.

     本篇文章要說(shuō)的線程掛起與繼續(xù)的方式其實(shí)是利用AutoResetEvent和ManualResetEvent的方法進(jìn)行堵塞和繼續(xù)的。

在介紹AutoResetEvent和ManualResetEvent之前,先介紹一個(gè)概念,就是線程中Set()和Reset()的區(qū)別。

  • set:指的是將一個(gè)事件設(shè)置為有信號(hào),那么被這個(gè)事件堵塞的線程就會(huì)繼續(xù)下去。
  • reset:指的是將一個(gè)事件設(shè)置為無(wú)信號(hào),那么嘗試?yán)^續(xù)的事件就會(huì)被堵塞。

一,AutoResetEvent類

     這個(gè)類的字面意思就能夠解釋一切:自動(dòng)reset的事件,就是這個(gè)事件一旦set之后,如果某個(gè)線程堵塞被繼續(xù)了,那么就會(huì)自動(dòng)reset。下一次如果嘗試?yán)^續(xù),依然會(huì)被堵塞。

      其中AutoResetEvent類的構(gòu)造函數(shù)有一個(gè)參數(shù) 是bool型。

     MSDN的解釋是:

      Initializes a new instance of the AutoResetEvent class with a Boolean value indicating whether to set the initial state to signaled.

    如果這個(gè)參數(shù)是true,那么第一次嘗試?yán)^續(xù)就不會(huì)被阻塞。如果這個(gè)參數(shù)是false,那么第一次嘗試?yán)^續(xù)就會(huì)被堵塞。

    以下是測(cè)試代碼,取自MSDN:

using System;
using System.Threading;

// Visual Studio: Replace the default class in a Console project with 
//                the following class.
class Example
{
    private static AutoResetEvent event_1 = new AutoResetEvent(true);
    private static AutoResetEvent event_2 = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Press Enter to create three threads and start them.\r\n" +
                          "The threads wait on AutoResetEvent #1, which was created\r\n" +
                          "in the signaled state, so the first thread is released.\r\n" +
                          "This puts AutoResetEvent #1 into the unsignaled state.");
        Console.ReadLine();

        for (int i = 1; i < 4; i++)
        {
            Thread t = new Thread(ThreadProc);
            t.Name = "Thread_" + i;
            t.Start();
        }
        Thread.Sleep(250);

        for (int i = 0; i < 2; i++)
        {
            Console.WriteLine("Press Enter to release another thread.");
            Console.ReadLine();
            event_1.Set();
            Thread.Sleep(250);
        }

        Console.WriteLine("\r\nAll threads are now waiting on AutoResetEvent #2.");
        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine("Press Enter to release a thread.");
            Console.ReadLine();
            event_2.Set();
            Thread.Sleep(250);
        }

        // Visual Studio: Uncomment the following line.
        //Console.Readline();
    }

    static void ThreadProc()
    {
        string name = Thread.CurrentThread.Name;

        Console.WriteLine("{0} waits on AutoResetEvent #1.", name);
        event_1.WaitOne();
        Console.WriteLine("{0} is released from AutoResetEvent #1.", name);

        Console.WriteLine("{0} waits on AutoResetEvent #2.", name);
        event_2.WaitOne();
        Console.WriteLine("{0} is released from AutoResetEvent #2.", name);

        Console.WriteLine("{0} ends.", name);
    }
}

其中,AutoResetEvent.WaitOne()這個(gè)方法就是線程中嘗試?yán)^續(xù)。如果沒(méi)有SET信號(hào),那么就會(huì)一直阻塞,如果收到Set信號(hào)該線程就會(huì)繼續(xù)。但是因?yàn)槭茿utoResetEvent,所以下一次waitOne依然會(huì)被阻塞。

上面代碼的輸出結(jié)果是:

Press Enter to create three threads and start them.
The threads wait on AutoResetEvent #1, which was created
in the signaled state, so the first thread is released.
This puts AutoResetEvent #1 into the unsignaled state.

Thread_1 waits on AutoResetEvent #1.
Thread_1 is released from AutoResetEvent #1.
Thread_1 waits on AutoResetEvent #2.
Thread_3 waits on AutoResetEvent #1.
Thread_2 waits on AutoResetEvent #1.
Press Enter to release another thread.

Thread_3 is released from AutoResetEvent #1.
Thread_3 waits on AutoResetEvent #2.
Press Enter to release another thread.

Thread_2 is released from AutoResetEvent #1.
Thread_2 waits on AutoResetEvent #2.

All threads are now waiting on AutoResetEvent #2.
Press Enter to release a thread.

Thread_2 is released from AutoResetEvent #2.
Thread_2 ends.
Press Enter to release a thread.

Thread_1 is released from AutoResetEvent #2.
Thread_1 ends.
Press Enter to release a thread.

Thread_3 is released from AutoResetEvent #2.
Thread_3 ends.

二,ManualResetEvent

ManualResetEvent和AutoResetEvent大部分概念都是相同的,最大的不同就是一個(gè)是自動(dòng)reset一個(gè)是手動(dòng)reset。也就是說(shuō),如果使用ManualResetEvent類,一旦Set之后,所有已經(jīng)阻塞的線程(waitone())都會(huì)繼續(xù)。而且之后調(diào)用waitone的線程也不會(huì)被堵塞,除非手動(dòng)再次Reset。也就是說(shuō),這個(gè)類是手動(dòng)開(kāi)啟關(guān)閉信號(hào)的事件。

以下是測(cè)試代碼,取自MSDN:

using System;
using System.Threading;

public class Example
{
    // mre is used to block and release threads manually. It is
    // created in the unsignaled state.
    private static ManualResetEvent mre = new ManualResetEvent(false);

    static void Main()
    {
        Console.WriteLine("\nStart 3 named threads that block on a ManualResetEvent:\n");

        for(int i = 0; i <= 2; i++)
        {
            Thread t = new Thread(ThreadProc);
            t.Name = "Thread_" + i;
            t.Start();
        }

        Thread.Sleep(500);
        Console.WriteLine("\nWhen all three threads have started, press Enter to call Set()" +
                          "\nto release all the threads.\n");
        Console.ReadLine();

        mre.Set();

        Thread.Sleep(500);
        Console.WriteLine("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" +
                          "\ndo not block. Press Enter to show this.\n");
        Console.ReadLine();

        for(int i = 3; i <= 4; i++)
        {
            Thread t = new Thread(ThreadProc);
            t.Name = "Thread_" + i;
            t.Start();
        }

        Thread.Sleep(500);
        Console.WriteLine("\nPress Enter to call Reset(), so that threads once again block" +
                          "\nwhen they call WaitOne().\n");
        Console.ReadLine();

        mre.Reset();

        // Start a thread that waits on the ManualResetEvent.
        Thread t5 = new Thread(ThreadProc);
        t5.Name = "Thread_5";
        t5.Start();

        Thread.Sleep(500);
        Console.WriteLine("\nPress Enter to call Set() and conclude the demo.");
        Console.ReadLine();

        mre.Set();

        // If you run this example in Visual Studio, uncomment the following line:
        //Console.ReadLine();
    }


    private static void ThreadProc()
    {
        string name = Thread.CurrentThread.Name;

        Console.WriteLine(name + " starts and calls mre.WaitOne()");

        mre.WaitOne();

        Console.WriteLine(name + " ends.");
    }
}

輸出結(jié)果是:

Start 3 named threads that block on a ManualResetEvent:

Thread_0 starts and calls mre.WaitOne()
Thread_1 starts and calls mre.WaitOne()
Thread_2 starts and calls mre.WaitOne()

When all three threads have started, press Enter to call Set()
to release all the threads.


Thread_2 ends.
Thread_0 ends.
Thread_1 ends.

When a ManualResetEvent is signaled, threads that call WaitOne()
do not block. Press Enter to show this.


Thread_3 starts and calls mre.WaitOne()
Thread_3 ends.
Thread_4 starts and calls mre.WaitOne()
Thread_4 ends.

Press Enter to call Reset(), so that threads once again block
when they call WaitOne().


Thread_5 starts and calls mre.WaitOne()

Press Enter to call Set() and conclude the demo.

Thread_5 ends.

ManualResetEvent類的輸出結(jié)果與AutoResetEvent輸出結(jié)果最大的不同是在于:

如果不手動(dòng)Reset,一旦調(diào)用Set方法,那么ManualResetEvent.WaitOne()就不會(huì)堵塞。

但是,AutoResetEvent會(huì)自動(dòng)Reset,所以哪怕不手動(dòng)Reset,每一次AutoResetEvent.WaitOne()都需要Set方法進(jìn)行觸發(fā)以繼續(xù)線程。

以上就是詳解C# 線程的掛起與喚醒的詳細(xì)內(nèi)容,更多關(guān)于C# 線程的掛起與喚醒的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#控制臺(tái)模擬電梯工作原理

    C#控制臺(tái)模擬電梯工作原理

    簡(jiǎn)單的模擬一下電梯的運(yùn)行,電梯內(nèi)部和外部樓層呼叫的優(yōu)先級(jí)判斷。以前學(xué)硬件的時(shí)候做這個(gè)不成問(wèn)題,現(xiàn)在用軟件來(lái)模擬對(duì)我來(lái)說(shuō)比較難,要C#的圖形界面。求高手賜教。
    2015-06-06
  • C#實(shí)現(xiàn)CSV文件讀寫(xiě)的示例詳解

    C#實(shí)現(xiàn)CSV文件讀寫(xiě)的示例詳解

    這篇文章主要介紹了CsvHelper、TextFieldParser、正則表達(dá)式三種解析CSV文件的方法,順帶也會(huì)介紹一下CSV文件的寫(xiě)方法,需要的可以參考一下
    2023-05-05
  • C# CultureInfo之常用InvariantCulture案例詳解

    C# CultureInfo之常用InvariantCulture案例詳解

    這篇文章主要介紹了C# CultureInfo之常用InvariantCulture案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C#控件閃爍的解決方法

    C#控件閃爍的解決方法

    這篇文章主要介紹了C#控件閃爍的解決方法,涉及SetStyle函數(shù)的使用技巧,需要的朋友可以參考下
    2015-01-01
  • C#Js時(shí)間格式化問(wèn)題簡(jiǎn)單實(shí)例

    C#Js時(shí)間格式化問(wèn)題簡(jiǎn)單實(shí)例

    這篇文章介紹了C#Js時(shí)間格式化問(wèn)題簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下
    2013-10-10
  • c#使用FreeSql生產(chǎn)環(huán)境時(shí)自動(dòng)升級(jí)備份數(shù)據(jù)庫(kù)

    c#使用FreeSql生產(chǎn)環(huán)境時(shí)自動(dòng)升級(jí)備份數(shù)據(jù)庫(kù)

    使用FreeSql,包含所有的ORM數(shù)據(jù)庫(kù),都會(huì)存在這樣的問(wèn)題。在codefirst模式下,根據(jù)代碼自動(dòng)更新數(shù)據(jù)庫(kù),都建議不要在生產(chǎn)環(huán)境使用。因?yàn)槿菀讈G失數(shù)據(jù),本文提供一種自動(dòng)更新數(shù)據(jù)庫(kù)的解決的思路:在判斷需要升級(jí)時(shí),才自動(dòng)升級(jí),同時(shí)升級(jí)前先備份數(shù)據(jù)庫(kù)
    2021-06-06
  • C#中使用gRPC通訊的示例詳解

    C#中使用gRPC通訊的示例詳解

    這篇文章主要為大家詳細(xì)介紹了C#中如何使用gRPC通訊,包括GRPC文件的創(chuàng)建生成、服務(wù)端和客戶端函數(shù)類庫(kù)的封裝等,需要的可以了解下
    2024-04-04
  • c#通過(guò)進(jìn)程調(diào)用cmd判斷登錄用戶權(quán)限代碼分享

    c#通過(guò)進(jìn)程調(diào)用cmd判斷登錄用戶權(quán)限代碼分享

    最近自己開(kāi)發(fā)軟件需要讀取本地配置文件,因?yàn)榈卿浻脩舻臋?quán)限不夠會(huì)導(dǎo)致無(wú)法讀取文件進(jìn)而導(dǎo)致程序崩潰,查了一些解決方法,代碼分享如下
    2013-12-12
  • WPF彈出自定義窗口的方法

    WPF彈出自定義窗口的方法

    這篇文章主要介紹了WPF彈出自定義窗口的方法,結(jié)合實(shí)例形式分析了WPF自定義窗口的創(chuàng)建與調(diào)用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 淺談Async和Await如何簡(jiǎn)化異步編程(幾個(gè)實(shí)例讓你徹底明白)

    淺談Async和Await如何簡(jiǎn)化異步編程(幾個(gè)實(shí)例讓你徹底明白)

    本篇文章主要介紹了淺談Async和Await如何簡(jiǎn)化異步編程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12

最新評(píng)論

西乡县| 佛教| 商丘市| 泰和县| 涪陵区| 北安市| 思南县| 雷波县| 哈巴河县| 托里县| 新邵县| 芦山县| 福海县| 沙洋县| 四川省| 饶河县| 五台县| 乌兰察布市| 衡阳市| 静安区| 布尔津县| 莆田市| 冀州市| 西充县| 满城县| 塘沽区| 乌兰察布市| 共和县| 长阳| 兴和县| 桦川县| 醴陵市| 凤冈县| 泉州市| 清镇市| 化德县| 行唐县| 常德市| 新绛县| 台东市| 合山市|