Зависает поток - C#

Узнай цену своей работы

Формулировка задачи:

Есть код, реализующий доступ "читателей" и "писателей" к буферу Используются сигнальные сообщения. Дойдя до строки
foreach (var t in writers)
                t.Join();
Дальше код не выполняется, ошибок никаких не выдается. пробовал отладчиком - везде наставил точки, но никуда и не заходит
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        private static String buffer = null;
        private static bool finish = false;

        static void Main(string[] args)
        {
            Console.Write("Количество читателей: ");
            var CountReder = Convert.ToInt32(Console.ReadLine());
 
            Console.Write("Количество писателей: ");
            int CountWriter = Convert.ToInt32(Console.ReadLine());
 
            var readers = new Thread[CountReder];
            var writers = new Thread[CountWriter];
 
            var Event = new AutoResetEvent[2];
            Event[0] = new AutoResetEvent(false);
            Event[1] = new AutoResetEvent(false);
            var sw = new Stopwatch();
            sw.Start();
 
            for (var i = 0; i < readers.Length; i++)
            {
                readers[i] = new Thread(Reader);
                readers[i].Start(Event);
            }
 
            for (var i = 0; i < writers.Length; i++)
            {
                writers[i] = new Thread(Writer);
                writers[i].Start(Event);
            }

            foreach (var t in writers)
                t.Join();
            finish = true;
 
            foreach (var t in readers)
                t.Join();
            
            sw.Stop();
            TimeSpan ts = sw.Elapsed;
            Console.WriteLine("Общее время: {0} миллисекунд", ts.TotalMilliseconds);
            Console.ReadKey();
 
        }

        static void Reader(object state)
        {
            object[] data = (object[])state;
 
            var evFull = data[0] as AutoResetEvent;
            var evEmpty = data[1] as AutoResetEvent;
            
            var msg = new List<string>();
 
            while (true)
            {
                evFull.WaitOne();
                // Сигнал о завершении работы 
                if (finish) break;
                msg.Add(buffer);
                evEmpty.Set(); 
            }
        }
 
        static void Writer(object state)
        {
            object[] data = (object[]) state;
            
            var evFull = data[0] as AutoResetEvent;
            var evEmpty = data[1] as AutoResetEvent;
 
            string[] msg =
            {
                "первое сообщение",
                "второе сообщение",
                "третие сообщение"
            };
            
            int i = 0;
 
            while (i < msg.Length)
            {
                evEmpty.WaitOne();
                buffer = msg[i++];
                  evFull.Set(); 
            }
        }
    }
}

Решение задачи: «Зависает поток»

textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace lab3
{
    class Program
    {
        //список, куда потоки-читатели записывают прочтенную информацию с буфера
        static List<string> bufferHistory;
        static string buffer;
        static Thread[] writers, readers;
        static bool  isWriteCompleted;
        //общее количество информации, которую надо записать
        static int dataCount = 10000;
        static int writersCount = 4, readersCount = 4;
        static int dataPerThread = dataCount / writersCount;
        static AutoResetEvent bufferEmpty, bufferFull;
        static void Main(string[] args)
        {
           
                DateTime from = DateTime.Now;
                bufferHistory = new List<string>();
                //устанавливаем флаг, что буфер пуст
                bufferEmpty = new AutoResetEvent(true);
                //что буфер неполон
                bufferFull = new AutoResetEvent(false);
                writers = new Thread[writersCount];
                readers = new Thread[readersCount];
                //создание потоков-писателей
                for (int i = 0; i < writersCount; i++)
                {
                    Thread writer = new Thread(WriterThread);
                    writer.Name = "W" + i;
                    writers[i] = writer;
                }
                //создание потоков-читателей
                for (int i = 0; i < readersCount; i++)
                {
                    Thread reader = new Thread(ReaderThread);
                    readers[i] = reader;
                }
                //запуск потоков-писателей
                for (int i = 0; i < writersCount; i++)
                {
                    writers[i].Start();
                }
                //запуск потоков-читателей
                for (int i = 0; i < readersCount; i++)
                {
                    readers[i].Start();
                }
                //ожидание выполнения потоков-писателей
                for (int i = 0; i < writersCount; i++)
                {
                    writers[i].Join();
                }
                isWriteCompleted = true;
                bufferFull.Set();
                //ожидание выполнения потоков-читателей
                for (int i = 0; i < readersCount; i++)
                {
                    readers[i].Join();
                }
                DateTime to = DateTime.Now;
                double cur = (to - from).TotalMilliseconds;
 
                //foreach (string str in bufferHistory)
                //    Console.WriteLine(str);
                Console.WriteLine("Threads: {0}/{1}, perThread: {2} = {3}", writersCount, readersCount, dataPerThread, cur);
        }
        static void WriterThread()
        {
            int i = 0;
            while (i < dataPerThread)
            {
                bufferEmpty.WaitOne();
                buffer = Thread.CurrentThread.Name + "_" + i;
                i++;
                bufferFull.Set();
            }
        }
        static void ReaderThread()
        {
            while (!isWriteCompleted)
            {
                bufferFull.WaitOne();
                if (isWriteCompleted)
                {
                    bufferFull.Set();
                    break;
                }
                bufferHistory.Add(buffer);
                bufferEmpty.Set();
            }
            
        }
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.929 из 5
Похожие ответы