0

在下面的代码中,我试图同时启动两个工作人员,以便总经过时间和个人经过的时间相互匹配。我预计所有经过的时间为 1000 毫秒(+ 说 3 毫秒的延迟),所有工作人员的个人经过的时间为 1000 毫秒。

但是我得到的输出好像所有的工人都是按顺序运行的。

OverAll Elapsed Time: 2001
Individual Elapsed Time: 1000
Individual Elapsed Time: 999

你能解释一下我错过了什么吗?

class Program
{
    static int m_NumberOfWorkers = 2;
    static readonly object m_Locker = new object();
    static bool flag_GO = false;
    static Stopwatch m_OverAllStopwatch = new Stopwatch();
    static ConcurrentBag<Stopwatch> m_bagIndividualStopwatch = new ConcurrentBag<Stopwatch>();
    static int m_CompletedWorkers = 0;
    static void Main(string[] args)
    {   
        // Create Workers
        List<Thread> lstThreads = new List<Thread>();
        for (int i = 0; i < m_NumberOfWorkers; ++i)
        {
            lstThreads.Add(new Thread(ConcurrentMethod));
        }

        // Start Workers
        for (int i = 0; i < lstThreads.Count; ++i)
        {
            lstThreads[i].Start();
        }

        m_OverAllStopwatch.Start();

        // Signal all workers
        lock (m_Locker)
        {
            flag_GO = true;
            Monitor.PulseAll(m_Locker);
        }

        // Wait all workers to finish
        for (int i = 0; i < lstThreads.Count; ++i)
        {
            lstThreads[i].Join();
        }

        Console.Read();
    }

    private static void ConcurrentMethod()
    {
        lock (m_Locker)
        {
            while (!flag_GO) Monitor.Wait(m_Locker);
            TestWhatEverYouWant();
            IamDone();
        }
    }

    private static void TestWhatEverYouWant()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();
        Thread.Sleep(1000);
        stopWatch.Stop();
        m_bagIndividualStopwatch.Add(stopWatch);
    }

    private static void IamDone()
    {
        Interlocked.Increment(ref m_CompletedWorkers);
        // Summarize results if all workers are done
        if (Interlocked.CompareExchange(ref m_CompletedWorkers, 0, m_NumberOfWorkers) == m_NumberOfWorkers)
        {
            m_OverAllStopwatch.Stop();
            Console.WriteLine("OverAll Elapsed Time: {0}", m_OverAllStopwatch.ElapsedMilliseconds);
            foreach (Stopwatch stopWatch in m_bagIndividualStopwatch)
            {
                Console.WriteLine("Individual Elapsed Time: {0}", stopWatch.ElapsedMilliseconds);
            }
        }
    }        
}
4

1 回答 1

0

傻我:)我在锁里工作!!!将这些方法移出锁当然解决了这个问题。

    private static void ConcurrentMethod()
    {
        lock (m_Locker)
        {
            while (!flag_GO) Monitor.Wait(m_Locker);                
        }
        TestWhatEverYouWant();
        IamDone();
    }

我得到了想要的输出!!

OverAll Elapsed Time: 1004
Individual Elapsed Time: 1000
Individual Elapsed Time: 999
于 2012-11-29T07:06:50.127 回答