📜  c# 线程等待 - C# (1)

📅  最后修改于: 2023-12-03 15:29:48.098000             🧑  作者: Mango

C#线程等待

在多线程编程中,经常需要让一个线程等待另一个线程完成任务后再继续执行。C#提供了多种等待线程的方法,本文将介绍其中较为常用的几种方法。

Thread.Join

Thread.Join方法是让一个线程等待另一个线程完成的最简单的方法。该方法调用时会阻塞当前线程,直到等待的线程完成后才会继续执行。

Thread thread1 = new Thread(SomeMethod);
thread1.Start();
//等待thread1完成
thread1.Join();

上面的例子中,我们首先创建一个新的线程thread1,并调用其Start方法启动线程。然后在主线程中调用thread1的Join方法,等待thread1完成后才继续执行主线程。

需要注意的是,Join方法可以带一个超时参数,指定最长等待时间。如果等待时间超过指定的时间,Join方法会返回false,并让当前线程继续执行。

Task.Wait

Task.Wait方法是等待一个异步任务完成的方法。它可以阻塞当前线程,直到异步任务完成为止。

Task<int> task1 = Task.Run(SomeMethodAsync);
//等待task1完成
task1.Wait();

上面的例子中,我们首先创建一个异步任务task1,然后调用其Wait方法等待task1完成。

需要注意的是,如果异步任务抛出异常,Wait方法会将该异常重新抛出,需要在调用Wait方法前使用try catch语句捕获异常。

Task.Result

Task.Result属性同样可以让当前线程等待异步任务完成。它会阻塞当前线程,直到异步任务完成并返回结果。

Task<int> task1 = Task.Run(SomeMethodAsync);
//等待task1完成并获取结果
int result = task1.Result;

上面的例子中,我们首先创建一个异步任务task1,然后通过其Result属性等待task1完成并获取其结果。

需要注意的是,如果异步任务抛出异常,访问Result属性会抛出AggregateException异常,需要在访问Result属性前使用try catch语句捕获异常。

ManualResetEvent.WaitOne

ManualResetEvent是一个线程同步的工具类,它可以用于在多个线程之间同步信号,使得一个线程等待另一个线程的信号。其中WaitOne方法可以让当前线程等待ManualResetEvent的信号。

ManualResetEvent mre = new ManualResetEvent(false);
Thread thread1 = new Thread(SomeMethod);
thread1.Start();
//等待thread1发送信号
mre.WaitOne();

上面的例子中,我们首先创建一个ManualResetEvent实例,并将其初始化为未发出信号的状态。然后创建一个新线程thread1,启动该线程执行一些操作。最后在主线程中等待thread1发出信号,使得主线程可以继续执行。

需要注意的是,当调用ManualResetEvent的Set方法发出信号后,ManualResetEvent会一直保持有信号的状态,直到调用其Reset方法将其重置为未发出信号的状态。因此,在使用ManualResetEvent时需要注意在适当的时候调用Reset方法。

AutoResetEvent.WaitOne

AutoResetEvent是另一个用于同步线程的工具类,其工作原理与ManualResetEvent类似。但是,AutoResetEvent只会在一个线程等待完后自动重置为未发出信号的状态,而不像ManualResetEvent一样需要手动重置。

AutoResetEvent are = new AutoResetEvent(false);
Thread thread1 = new Thread(SomeMethod);
thread1.Start();
//等待thread1发送信号
are.WaitOne();

上面的例子中,我们首先创建一个AutoResetEvent实例,并将其初始化为未发出信号的状态。然后创建一个新线程thread1,启动该线程执行一些操作。最后在主线程中等待thread1发出信号,使得主线程可以继续执行。

需要注意的是,如果有多个线程正在等待AutoResetEvent信号,只有一个线程会被唤醒。

SemaphoreSlim.Wait

SemaphoreSlim是一个同步工具类,它可以控制同时执行某个操作的线程数量。其中Wait方法可以让当前线程等待SemaphoreSlim信号。

SemaphoreSlim semaphore = new SemaphoreSlim(0);
Thread thread1 = new Thread(SomeMethod);
thread1.Start();
//等待thread1发送信号
semaphore.Wait();

上面的例子中,我们首先创建一个SemaphoreSlim实例,并将其初始化为0。然后创建一个新线程thread1,启动该线程执行一些操作。最后在主线程中等待thread1发出信号,使得主线程可以继续执行。

需要注意的是,SemaphoreSlim的初始值为0,需要通过Release方法使其增加信号,从而让等待的线程继续执行。

总结

以上介绍了C#中常用的几种等待线程的方法,需要根据具体的应用场景选择合适的方法。同时需要注意,在使用这些方法时需要遵守正确的线程同步方式,避免出现线程安全问题。