C# ManualResetEvent信號(hào)怎樣控制

c#
小樊
81
2024-10-12 08:46:00

ManualResetEvent 是 C# 中的一個(gè)同步原語(yǔ),它允許一個(gè)或多個(gè)線程等待,直到另一個(gè)線程設(shè)置一個(gè)事件。ManualResetEvent 的信號(hào)控制主要通過(guò)其 Set()Reset() 方法來(lái)實(shí)現(xiàn)。

  1. Set() 方法:當(dāng)調(diào)用 Set() 方法時(shí),如果 ManualResetEvent 當(dāng)前處于未信號(hào)狀態(tài)(即沒(méi)有線程在等待),則它會(huì)被設(shè)置為信號(hào)狀態(tài)。如果有線程正在等待,那么這些線程會(huì)立即被釋放并繼續(xù)執(zhí)行。如果 ManualResetEvent 已經(jīng)是信號(hào)狀態(tài),那么調(diào)用 Set() 方法不會(huì)有任何效果。
  2. Reset() 方法:當(dāng)調(diào)用 Reset() 方法時(shí),ManualResetEvent 會(huì)被設(shè)置為非信號(hào)狀態(tài)。這意味著任何正在等待該事件的線程都會(huì)被阻塞,直到再次調(diào)用 Set() 方法將其設(shè)置為信號(hào)狀態(tài)。

以下是一個(gè)簡(jiǎn)單的示例,展示了如何使用 ManualResetEvent 來(lái)同步線程:

using System;
using System.Threading;

class Program
{
    static ManualResetEvent _event = new ManualResetEvent(false); // 初始化為非信號(hào)狀態(tài)

    static void Main()
    {
        Thread thread1 = new Thread(DoWork);
        Thread thread2 = new Thread(DoWork);

        thread1.Start();
        thread2.Start();

        // 讓線程1先執(zhí)行
        _event.Set();

        thread1.Join();
        thread2.Join();
    }

    static void DoWork()
    {
        Console.WriteLine("Thread is waiting for event...");
        _event.WaitOne(); // 等待事件被設(shè)置為信號(hào)狀態(tài)
        Console.WriteLine("Event received. Thread continues.");
    }
}

在這個(gè)示例中,我們創(chuàng)建了兩個(gè)線程 thread1thread2,它們都調(diào)用 DoWork 方法。在 Main 方法中,我們首先啟動(dòng)這兩個(gè)線程,然后調(diào)用 _event.Set() 來(lái)設(shè)置事件,使得 thread1 可以立即繼續(xù)執(zhí)行。thread1 執(zhí)行完畢后,主線程調(diào)用 Join() 等待兩個(gè)線程都執(zhí)行完畢。

需要注意的是,ManualResetEvent 的信號(hào)狀態(tài)只能由一個(gè)線程來(lái)設(shè)置,其他線程必須等待該事件被設(shè)置后才能繼續(xù)執(zhí)行。如果多個(gè)線程同時(shí)調(diào)用 Set() 方法,那么只有第一個(gè)調(diào)用的線程會(huì)成功設(shè)置事件狀態(tài),其他線程會(huì)拋出異常。為了避免這種情況,可以使用 Monitor 或其他同步原語(yǔ)來(lái)確保只有一個(gè)線程能夠設(shè)置事件狀態(tài)。

0