Semaphore
在WPF中,Semaphore是System.Threading命名空间中的一个类,用于控制对共享资源的访问。
如果有多个线程需要同时访问某个共享资源,可以使用Semaphore来实现线程的同步和互斥。
Semaphore通常用于以下两种场景:
-
控制同时访问的线程数量:可以通过Semaphore的构造函数来指定初始的可用资源数量和最大资源数量。线程可以通过调用Semaphore的WaitOne方法来申请获取资源,如果资源被占用,则线程将等待。当线程释放资源后,Semaphore将通知等待的线程继续执行。
-
信号量控制流:Semaphore还可以用于控制流的顺序。通过设置Semaphore的初始资源数量为0,可以阻止某些线程继续执行,直到其他线程发送信号通知。
使用Semaphore通常需要在关键代码段前后获取和释放资源。可以通过调用WaitOne方法来获取Semaphore资源,并通过调用Release方法来释放Semaphore资源。
下面是一个示例,演示了如何在WPF中使用Semaphore:
using System.Threading; using System.Windows; public partial class MainWindow : Window { private Semaphore semaphore = new Semaphore(1, 1); public MainWindow() { InitializeComponent(); } private void AccessSharedResource() { // 获取Semaphore资源 semaphore.WaitOne(); // 访问共享资源 // ... // 释放Semaphore资源 semaphore.Release(); } private void Button_Click(object sender, RoutedEventArgs e) { // 在后台线程中访问共享资源 Thread t = new Thread(new ThreadStart(AccessSharedResource)); t.Start(); } }
在上述示例中,当按钮被点击时,将创建一个后台线程来访问共享资源。在AccessSharedResource方法中,首先通过调用semaphore.WaitOne方法获取Semaphore资源。然后进行共享资源的访问,使用完资源后,通过调用semaphore.Release方法释放Semaphore资源。
Semaphore
using System; using System.Threading; namespace ConsoleApp2 { internal class Program { // A semaphore that simulates a limited resource pool. // private static Semaphore _pool; // A padding interval to make the output more orderly. private static int _padding; private static void Main(string[] args) { // Create a semaphore that can satisfy up to three // concurrent requests. Use an initial count of zero, // so that the entire semaphore count is initially // owned by the main program thread. // _pool = new Semaphore(initialCount: 0, maximumCount: 3); // Create and start five numbered threads. // for (int i = 1; i <= 5; i++) { Thread t = new Thread(new ParameterizedThreadStart(Worker)); // Start the thread, passing the number. // t.Start(i); } // Wait for half a second, to allow all the // threads to start and to block on the semaphore. // Thread.Sleep(500); // The main thread starts out holding the entire // semaphore count. Calling Release(3) brings the // semaphore count back to its maximum value, and // allows the waiting threads to enter the semaphore, // up to three at a time. // Console.WriteLine("Main thread calls Release(3)."); //返回之前的计数 _pool.Release(releaseCount: 3); Console.WriteLine("Main thread exits."); //Thread 1 begins and waits for the semaphore. //Thread 2 begins and waits for the semaphore. //Thread 3 begins and waits for the semaphore. //Thread 4 begins and waits for the semaphore. //Thread 5 begins and waits for the semaphore. //Main thread calls Release(3). //Main thread exits. //Thread 2 enters the semaphore. //Thread 1 enters the semaphore. //Thread 3 enters the semaphore. //Thread 2 releases the semaphore. //releases //Thread 4 enters the semaphore. //Thread 2 previous semaphore count: 0 //Thread 1 releases the semaphore. //releases //Thread 1 previous semaphore count: 0 //Thread 5 enters the semaphore. //Thread 3 releases the semaphore. //releases //Thread 3 previous semaphore count: 0 //Thread 4 releases the semaphore. //releases //Thread 4 previous semaphore count: 1 //Thread 5 releases the semaphore. //releases //Thread 5 previous semaphore count: 2 } private static void Worker(object? num) { // Each worker thread begins by requesting the // semaphore. Console.WriteLine("Thread {0} begins " + "and waits for the semaphore.", num); _pool.WaitOne(); //bool wok= _pool.WaitOne(200); // A padding interval to make the output more orderly. int padding = Interlocked.Add(ref _padding, 100); Console.WriteLine("Thread {0} enters the semaphore.", num); // The thread's "work" consists of sleeping for // about a second. Each thread "works" a little // longer, just to make the output more orderly. // Thread.Sleep(1000 + padding); Console.WriteLine("Thread {0} releases the semaphore.", num); int prewcount = _pool.Release(); Console.WriteLine("Thread {0} previous semaphore count: {1}", num, prewcount); } } }
简单使用
在WPF中使用Semaphore的步骤如下:
- 引入命名空间 首先,在你的WPF代码文件中引入System.Threading命名空间,因为Semaphore位于这个命名空间下。你可以在文件的顶部添加这个引用语句:
using System.Threading;
- 创建Semaphore实例 在你的WPF类中,创建一个Semaphore实例。你可以在类的成员变量中声明Semaphore对象:
private Semaphore semaphore = new Semaphore(1, 1);
上述代码创建了一个初始容量为1,最大容量为1的Semaphore对象。这表示只有一个线程可以同时访问关键部分。
- 在关键地方获取和释放Semaphore 在你需要保护的重要代码段前后使用semaphore的WaitOne()和Release()方法进行获取和释放。
- 调用
WaitOne()
方法来获取Semaphore资源。这个方法会阻塞当前线程,直到资源可用。在获取资源之前,这个方法将等待或阻塞线程。
semaphore.WaitOne();
- 调用
Release()
方法来释放Semaphore资源。这个方法会通知Semaphore,资源已经不再被使用,可以让其他等待的线程继续执行。
semaphore.Release();
以下是一个简单的示例,演示了如何在WPF中使用Semaphore:
using System.Threading; using System.Windows; public partial class MainWindow : Window { private Semaphore semaphore = new Semaphore(1, 1); public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { // 获取Semaphore资源 semaphore.WaitOne(); // 临界区代码 // 在这里执行需要保护的代码 // 释放Semaphore资源 semaphore.Release(); } }
在上述示例中,当按钮被点击时,点击事件处理程序会获取Semaphore资源,然后执行临界区代码。当临界区代码执行完成后,会释放Semaphore资源,以便其他等待的线程可以获取资源并执行
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
2021-12-12 C# 多线程等待子线程结束 Task.Factory
2021-12-12 C# 多线程等待子线程全部完成 ThreadPool