C# AutoResetEvent

本文介绍了.NET线程同步机制中的AutoResetEvent。详细解释了AutoResetEvent如何通过WaitOne和Set方法实现线程间的信号传递,提供了具体的代码示例。

原文链接:http://dotnetpattern.com/threading-autoresetevent

AutoResetEvent是.net线程简易同步方法中的一种。

AutoResetEvent 常常被用来在两个线程之间进行信号发送

   两个线程共享相同的AutoResetEvent对象,线程可以通过调用AutoResetEvent对象的WaitOne()方法进入等待状态,然后另外一个线程通过调用AutoResetEvent对象的Set()方法取消等待的状态。

AutoResetEvent如何工作的

   在内存中保持着一个bool值,如果bool值为False,则使线程阻塞,反之,如果bool值为True,则使线程退出阻塞。当我们创建AutoResetEvent对象的实例时,我们在函数构造中传递默认的bool值,以下是实例化AutoResetEvent的例子。

AutoResetEvent autoResetEvent = new AutoResetEvent(false);
WaitOne 方法

该方法阻止当前线程继续执行,并使线程进入等待状态以获取其他线程发送的信号。WaitOne将当前线程置于一个休眠的线程状态。WaitOne方法收到信号后将返回True,否则将返回False。

autoResetEvent.WaitOne();

WaitOne方法的第二个重载版本是等待指定的秒数。如果在指定的秒数后,没有收到任何信号,那么后续代码将继续执行。

static void ThreadMethod()
{
    while(!autoResetEvent.WaitOne(TimeSpan.FromSeconds(2)))
    {
        Console.WriteLine("Continue");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
 
    Console.WriteLine("Thread got signal");
}

这里我们传递了2秒钟作为WaitOne方法的参数。在While循环中,autoResetEvent对象等待2秒,然后继续执行。当线程取得信号,WaitOne返回为True,然后退出循环,打印"Thread got signal"的消息。

Set 方法

AutoResetEvent Set方法发送信号到等待线程以继续其工作,以下是调用该方法的格式。

autoResetEvent.Set();

AutoResetEvent例子

下面的例子展示了如何使用AutoResetEvent来释放线程。在Main方法中,我们用Task Factory创建了一个线程,它调用了GetDataFromServer方法。调用该方法后,我们调用AutoResetEvent的WaitOne方法将主线程变为等待状态。在调用GetDataFromServer方法时,我们调用了AutoResetEvent对象的Set方法,它释放了主线程,并控制台打印输出dataFromServer方法返回的数据。

class Program
{
    static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
    static string dataFromServer = "";
 
    static void Main(string[] args)
    {
        Task task = Task.Factory.StartNew(() =>
        {
            GetDataFromServer();
        });
 
        //Put the current thread into waiting state until it receives the signal
        autoResetEvent.WaitOne();
 
        //Thread got the signal
        Console.WriteLine(dataFromServer);
    }
 
    static void GetDataFromServer()
    {
        //Calling any webservice to get data
        Thread.Sleep(TimeSpan.FromSeconds(4));
        dataFromServer = "Webservice data";
        autoResetEvent.Set();
    }
}

转载于:https://www.cnblogs.com/czytcn/p/8085071.html

<think>好的,我现在需要帮助用户了解C#AutoResetEvent的用法和相关问题。首先,我应该回忆一下AutoResetEvent的基本概念,它是用于线程同步的类,属于System.Threading命名空间。用户可能想知道如何正确使用它,以及常见的应用场景。 根据用户提供的引用内容,引用[3]提到了AutoResetEvent的初始状态为信号状态时不会阻塞线程,但遇到WaitOne()会转换为非信号状态。这说明用户可能对信号状态的变化机制感兴趣。我需要解释构造函数参数的作用,true表示初始为有信号状态,false则为无信号状态。 接下来,我需要给出一个基本示例,展示如何在一个线程中等待信号,另一个线程中设置信号。代码示例应该包括创建AutoResetEvent实例,启动线程,并使用WaitOne()和Set()方法。同时,要注意线程同步的典型模式,比如生产者-消费者场景。 然后,用户可能关心常见问题,比如忘记调用Set()导致死锁,或者错误使用多个AutoResetEvent实例的情况。需要指出这些陷阱,并提供解决方案,比如使用using语句管理资源,或者结合WaitHandle.WaitAll()处理多个等待。 参考用户提供的其他引用,虽然引用[1]和引用[2]主要涉及委托,可能与当前问题关联不大,但可能需要确认是否有相关内容需要关联。不过当前问题主要集中在AutoResetEvent,所以可以暂时忽略其他引用,专注于引用[3]的信息。 最后,生成相关问题时,要围绕AutoResetEvent的用法、与其他同步类的区别、实际应用案例以及常见错误处理等方面展开。确保问题能够引导用户进一步深入理解该主题。 总结步骤: 1. 解释AutoResetEvent的基本概念和构造函数参数。 2. 提供基本使用示例代码,并分步骤说明。 3. 分析常见问题及解决方法。 4. 根据用户引用和需求生成相关问题。</think>### C# AutoResetEvent的用法及示例 #### 一、基本概念 `AutoResetEvent` 是用于线程同步的类,通过信号机制控制线程执行顺序。其核心状态分为: - **信号状态**:线程调用`WaitOne()`时不会被阻塞[^3]。 - **非信号状态**:线程调用`WaitOne()`时会阻塞,直到其他线程调用`Set()`恢复信号状态。 构造函数参数含义: ```csharp var are = new AutoResetEvent(true); // true表示初始为信号状态 ``` #### 二、基本用法示例 ```csharp using System.Threading; class Program { static AutoResetEvent are = new AutoResetEvent(false); // 初始为非信号状态 static void Main() { Thread worker = new Thread(DoWork); worker.Start(); Console.WriteLine("主线程发送信号"); are.Set(); // 唤醒等待的线程 worker.Join(); } static void DoWork() { Console.WriteLine("工作线程等待信号"); are.WaitOne(); // 阻塞直到收到信号 Console.WriteLine("工作线程继续执行"); } } ``` **输出结果**: ``` 主线程发送信号 工作线程等待信号 工作线程继续执行 ``` #### 三、典型应用场景 1. **生产者-消费者模型**:生产者通知消费者数据就绪。 2. **多阶段任务同步**:确保线程按顺序执行特定阶段。 3. **异步操作完成通知**:如后台任务完成后触发回调。 #### 四、常见问题及解决方法 | 问题现象 | 原因 | 解决方案 | |---------|------|---------| | 线程永久阻塞 | 忘记调用`Set()` | 用`try-finally`确保触发 | | 多次`Set()`无效 | `AutoResetEvent`每次仅允许一个线程通过 | 改用`ManualResetEvent` | | 资源泄漏 | 未调用`Dispose()` | 使用`using`语句管理生命周期 | #### 五、进阶技巧 - **超时控制**:`WaitOne(5000)`设置最长等待5秒。 - **多事件等待**:结合`WaitHandle.WaitAll()`处理复杂同步逻辑。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值