如何才能正确地阻止方法,直到对象计数器获得> 0?

时间:2015-02-25 06:10:43

标签: c# multithreading asynchronous

你可以认为课堂很奇怪,但它具有教育意义,所以我必须这样做。

class petriPool {
    private int[] nodes = new int[3];
    private int counter;

    private readonly object _lock = new object(); 

    public petriPool (int n, int m) {
        this.nodes[0] = n;
        this.nodes[1] = 0;
        this.nodes[2] = 0;
        this.counter  = m;
    }

    public bool start() {
        lock (_lock) {
            if (this.nodes[0] != 0 && counter != 0) {
                this.nodes[0]--;
                this.nodes[1]++;
                counter--;
                return true;   
            } else
                return false;
    }}

    public bool stop() {
        lock (_lock) {
            if (this.nodes[1] != 0) {
                this.nodes[1]--;
                this.nodes[2]++;
                counter++;
                return true;   
            } else
                return false;
    }}
}

我需要让start()方法等到counter获得值> 0。我可以这样做:

public bool start() {
    while (this.counter == 0) {
        Thread.Sleep(10);
    }

    lock (_lock) {
        if (this.nodes[0] != 0 && counter != 0) {
            this.nodes[0]--;
            this.nodes[1]++;
            counter--;
            return true;   
        } else
            return false;
}}

但这不是更好的解决方案吗?我的意思是看起来我可以减少睡觉时间。

看看它需要什么。我在开始线程之前调用start,在线程结束时调用stop。因此,计数器必须反映同时运行的最大线程数。

2 个答案:

答案 0 :(得分:1)

这样的信令是通过使用事件类完成的。在您的情况下,ManualResetEventSlim就足够了。

您可以Wait代替while循环,当计数器达到零时,您可以Set

答案 1 :(得分:1)

您可以考虑使用`ManualResetEvent'来管理两个线程。

以下未经测试的代码可能有所帮助。

class petriPool 
{
    private int[] nodes = new int[3];
    private int counter;
    private ManualResetEvent mevent;

    private readonly object _lock = new object(); 

    public petriPool (int n, int m) 
    {
        mevent= new ManualResetEvent(false);
        this.nodes[0] = n;
        this.nodes[1] = 0;
        this.nodes[2] = 0;
        this.counter  = m;
    }

    public bool start() 
    {
        lock (_lock) 
        {
            if (this.nodes[0] != 0 && counter != 0) 
            {
                this.nodes[0]--;
                this.nodes[1]++;
                counter--;

                if(counter>0) mevent.Set();

                return true;   
            } else
                return false;   
        }
    }

    public bool stop() 
    {
        mevent.WaitOne();

        lock (_lock) {


            if (this.nodes[1] != 0) {
                this.nodes[1]--;
                this.nodes[2]++;
                counter++;
                return true;   
            } else
                return false;
        }

        //reset 'mevent' if you want.
    }
}