多线程使用ThreadPool和countdowevent

本文关键字:countdowevent ThreadPool 多线程 | 更新日期: 2023-09-27 17:50:32

我得到了CountdownEvent使用的一个例子,但是当我通过示例代码时,我只是不明白它在做什么,以及CountdownEventSignal() and AddCount()如何帮助多线程同步。

这是样品。请有人帮助我了解同步是如何工作的多线程在这个例子中,Signal() and AddCount()使用。

class Program
{
    static void Main(string[] args)
    {
        using (CountdownEvent e = new CountdownEvent(1))
        {
            // fork work: 
            for (int i = 1; i <= 5;i++ )
            {
                // Dynamically increment signal count.
                TaskInfo ti = new TaskInfo("Current Thread ", i);
                Console.WriteLine("Running thread " + e.CurrentCount);
                e.AddCount();
                ThreadPool.QueueUserWorkItem(delegate(object state)
                {
                    try
                    {
                        //ProcessData(state);
                        TaskInfo inner_ti = (TaskInfo)state;
                        //Console.WriteLine(inner_ti.Boilerplate + inner_ti.Value);
                        Thread.Sleep(2000);
                    }
                    finally
                    {
                        Console.WriteLine("Signal thread " + e.CurrentCount);
                        e.Signal();
                    }
                },
                 ti);
            }
            Console.WriteLine("Outer Signal thread " + e.CurrentCount);
            e.Signal();
            // The first element could be run on this thread. 
            // Join with work.
            Console.WriteLine("Wait thread ");
            e.Wait();
            Console.WriteLine("ReadLine..... ");
            Console.ReadLine();
        }
    }
}
public class TaskInfo
{
    // State information for the task.  These members 
    // can be implemented as read-only properties, read/write 
    // properties with validation, and so on, as required. 
    public string Boilerplate;
    public int Value;
    // Public constructor provides an easy way to supply all 
    // the information needed for the task. 
    public TaskInfo(string text, int number)
    {
        Boilerplate = text;
        Value = number;
    }
}

只是用小的示例代码来指导我,比如Signal() and AddCount()是如何在现实生活中用于线程同步的。由于

多线程使用ThreadPool和countdowevent

CountdownEvent的任务是提供一个可等待对象(即一个对象将阻塞当前线程的请求,直到满足某些条件),其中需要满足的条件是该对象的内部计数器达到0的值。

您所展示的代码将用1的计数初始化CountdownEvent对象。这个值代表主线程本身;主线程稍后将调用Signal(),表示它已经完成了自己的工作(即启动其他五个线程)。

对于每创建一个新任务,主线程增加—调用AddCount()方法—在启动新任务之前,将CountdownEvent对象的计数器减少一个(在本例中,通过将任务排队到全局线程池)。每个任务完成后,将通过调用Signal()方法减少对象的计数器。

因此,最初,代码反复增加计数器,从初始值1,到最大值6

任务完成后,主线程立即将计数器减为5。每个任务完成后,会再次减少计数器。5个任务意味着计数器递减5次,所以当最后一个任务完成时,计数器将达到0

记住:CountdownEvent对象的目的是在它的内部计数器到达0时释放一个正在等待它的线程。(或者更具体地说,将可等待对象设置为其有信号的非阻塞状态)。

主线程调用CountdownEvent对象上的Wait()方法,这最初导致主线程阻塞(即等待)。它将继续等待,直到CountdownEvent被设置为非阻塞状态,这发生在它的内部计数器到达0时,这发生在最后一个任务完成时。

主线程等待最后一个任务完成。

只是用小的示例代码来指导我,比如Signal()和AddCount()是如何在现实生活中用于线程同步的

你在这里发布的代码示例看起来足够"真实"。我上面的描述解释了代码示例是如何工作的。您可以在任何场景中使用CountdownEvent对象,其中您有一些特定的操作,任务,事件等计数,这些计数应该在某些特定线程等待后继续之前发生。

当然,并不是所有的同步场景都包含这种需求。还有其他不同的同步机制可用于其他场景。CountdownEvent特别适用于那些等待线程通过完成倒计时来解除阻塞的场景,因此类的名称。