Многопоточное консольное приложение C#
Формулировка задачи:
Здравствуйте,подскажите пожалуйста как сделать это задание? Потоки знаю,сделать смогу. Не знаю как сделать ООП и не понимаю с статистикой вывода и форматом командной строки.Исключения тоже сделать смогу,однако не понимаю зачем они здесь.И как сделать Y? п.2
Многопоточное консольное приложение C#.
Основной поток запускает X (1 < X <= 64) вспомогательных потоков. X - первый параметр командной строки.
Каждый из вспомогательных потоков бесконечно (с некоторой изменяющейся
задержкой) добавляет в некий общий контейнер свой элемент.
При этом он удаляет самый старый элемент в случае, если тот был добавлен другим потоком или если количество элементов в контейнере > Y (Y - второй параметр командной строки).
Основной поток ожидает любого ввода из командной строки (например нажатия на Enter).
После получения ввода из командной строки основной поток должен распечатать статистику вида '<поток> - <количество элементов для этого потока в контейнере>' для всех потоков (вспомогательные потоки больше использоваться не будут) и максимальное зарегистрированное количество элементов в контейнере.
После этого приложение должно корректно завершиться.
Основные условия и требования:
1. Формат командной строки 'test_app X Y'.
2. Y - целое число на величину которого ограничение не накладывается (в рамках ограничения типа переменной).
3. Код должен безопасно обрабатывать возможные исключения, т.е предполагается что любой из потоков может формировать C# исключение в любой точке кода.
При этом общая работоспособность приложения должна сохраняться, либо приложение должно корректно завершиться если исключение произошло в основном потоке.
4. Код должен быть объектно ориентирован.
5. Приложение должно обеспечивать оптимальную скорость как для накопления, так и для отображения статистики.
6.Тест должен быть выполнен с использованием Visual Studio.
Решение задачи: «Многопоточное консольное приложение C#»
textual
Листинг программы
using System;
using System.Threading;
namespace test_app
{
class Program
{
static bool exit = false;
static volatile ItemContainer items;
static AutoResetEvent ready;
static Random rnd;
static void Main(string[] args)
{
int X = 0;
int Y = 0;
if (args.Length < 2)
{
Console.WriteLine("Недостаточно параметров\nНажмите enter для выхода");
Console.ReadLine();
return;
}
try
{
X = int.Parse(args[0]);
Y = int.Parse(args[1]);
}
catch (Exception err)
{
Console.WriteLine("Неверные параметры командной строки: {0}\nНажмите enter для выхода", err.Message);
Console.ReadLine();
return;
}
Thread[] threads = new Thread[X];
items = new ItemContainer(Y);
ready = new AutoResetEvent(true);
rnd = new Random();
Console.WriteLine("Кол-во потоков: {0}, предел контейнера: {1}", X, Y);
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(Adder);
threads[i].IsBackground = true;
threads[i].Start(i);
Thread.Sleep(100);
}
Console.WriteLine("Нажмите enter для прерывания");
Console.ReadLine();
exit = true;
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join();
Console.WriteLine("Поток {0}: {1} элементов", i, items.GetItemCount(i));
}
Console.WriteLine("Максимум элементов: {0}\n\nНажмите enter для выхода", items.Maximum);
Console.ReadLine();
}
private static void Adder(object i)
{
int item = (int)i;
for (; ; )
{
try
{
if (exit)
break;
ready.WaitOne();
items.AddItem(item);
ready.Set();
Thread.Sleep(rnd.Next(0, 1000));
}
catch (Exception err)
{
Console.WriteLine("Ошибка в потоке {0}: {1}", item, err.Message);
return;
}
}
}
}
}