任务并不起作用

时间:2014-04-06 09:15:23

标签: c# task-parallel-library task producer-consumer

我有两个任务作为生产者和消费者,但它们并不是并行运行的。第二个等待第一个竞争。你能解释一下为什么以及如何纠正这个问题?我希望他们两个同时运行。 (我尝试了很多varians,但所有这些都不能很好地工作)

class DirectoryReader
    {
        private readonly string _dir ;
        private Processor[] _processors;
        private string[] _files;
        private readonly Regex _rx = new Regex(@"([^.\\]+)\.cs");

        private Queue<Processor> queue = new Queue<Processor>();
        private bool isOff;
        private AutoResetEvent isAvailable = new AutoResetEvent(false);
        private StreamWriter log = new StreamWriter("Log.txt");



        public DirectoryReader(string dir)
        {
            _dir = dir; 
        }

        public Container[] ProcessAllFiles()
        {
            _files = Directory.GetFiles(_dir, "*.cs", SearchOption.AllDirectories);
            _processors = new Processor[_files.Length];                   

            var thread = Task.Run(() => Compute());
            var thread2 = Task.Run(() => Read());           
            thread.Wait();          
        }

        public void Read()
        {
                for (var i = 0; i < _files.Length; i++)
                {
                    try
                    {
                        var matches = _rx.Matches(_files[i]);
                        foreach (var match in matches)
                        {
                            //Console.WriteLine(match);
                            lock (log)
                            {
                                log.WriteLine(match);
                            }
                        }
                        _processors[i] = new Processor(matches[matches.Count - 1].ToString(), File.ReadAllText(_files[i]));
                        lock (queue)
                        {
                            queue.Enqueue(_processors[i]);
                            isAvailable.Set();
                        }

                    }
                    catch (IOException ex)
                    {
                        Console.WriteLine(ex.Message + _files[i]);
                    }

                }
                isOff = true;
            }

        public void Compute()
        {
            Processor proc = null;
            int ccount = 0;
            while (true)
            {
                lock (queue)
                {
                    if ((ccount = queue.Count) > 0)
                    {
                        proc = queue.Dequeue();
                    }
                }
                if (ccount == 0)
                {
                    if (isOff)
                    {
                        return;
                    }
                    else
                    {
                        isAvailable.WaitOne();
                    }
                }
                if (proc != null)
                {
                    //Some calculations on proc
                    lock (log)
                    {
                        log.WriteLine("+++++" + proc.FileName);
                    }
                }

            }
        }
    }

UPD1:我使用BlockingCollection重写此代码,但仍然无法正常运行

class DirectoryReader
    {
        private readonly string _dir ;
        private Processor[] _processors;
        private string[] _files;
        private readonly Regex _rx = new Regex(@"([^.\\]+)\.cs");
        private List<Container> answer = new List<Container>();       
        BlockingCollection<FileContainer> dataItems = new BlockingCollection<FileContainer>();

        public DirectoryReader(string dir)
        {
            _dir = dir; 
        }

        public void ProcessAllFiles()
        {
            _files = Directory.GetFiles(_dir, "*.cs", SearchOption.AllDirectories);
            _processors = new Processor[_files.Length];

            var task = Task.Factory.StartNew(Compute);
            var task2 = Task.Factory.StartNew(Read);
            Task.WaitAll(task, task2);
        }

        public void Read()
        {
            for (var i = 0; i < _files.Length; i++)
            {
                try
                {
                    var matches = _rx.Matches(_files[i]);                                          
                    dataItems.Add(new FileContainer{
                        Name = matches[matches.Count - 1].ToString(),
                        Content = File.ReadAllText(_files[i])});                       
                }
                catch (IOException ex)
                {
                    Console.WriteLine(ex.Message + _files[i]);
                }

            }
            dataItems.CompleteAdding();
        }

        public void Compute()
        {
            FileContainer proc = null;
            while (!dataItems.IsCompleted)
            {
                try
                {
                    proc = dataItems.Take();
                }
                catch (InvalidOperationException) { }
                if (proc != null)
                {
                    //Some calculations
                }
            }
        }
    }

0 个答案:

没有答案