using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using System.Text.RegularExpressions;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public const int N = 100; // максимальное количество процессов
public int kvant; // шаг в секундах (задается из блокнота)
public int cur_time = 0; // текущее время в секундах
public int lib_time = 0; // независимое время
public int count = 0; // количество поданных процессов
public int[] id = new int[N]; // IDs всех процессов
public string[] name = new string[N]; // имена процессов
public int[] begin_time = new int[N]; // время начала
public int[] priority = new int[N]; // 1-10 (1 — самый высокий)
public int[] process_time = new int[N]; // продолжительность процесса (в секундах)
public int current_proc = -1; // Текущий id процесса. Если -1 — очередь пуста.
public int current_proc_time;
public int sum_time = 0; // время всех процессов (в секундах)
public ArrayList queue = new ArrayList(); // очередь из IDs процессов в режиме готовности.
public ArrayList lost_queue = new ArrayList(); // IDs процессов, которые больше не попадут в очередь.
private void button1_Click(object sender, EventArgs e) // @"Начать"
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e) // @timer
{
if (this.cur_time < this.sum_time + this.kvant)
{
this.refreshQueue();
this.increment();
this.drawStateProcesses();
}
else
{
timer1.Enabled = false;
}
}
private void button2_Click(object sender, EventArgs e) // @ "Остановить"
{
24
timer1.Enabled = false;
}
private void button3_Click(object sender, EventArgs e) // @ "Считать"
{
this.initialize();
this.drawAxes();
this.drawLegend();
timer1.Interval = trackBar1.Value * 10 * this.kvant;
button3.Visible = false;
button2.Visible = true;
}
public void initialize()
{
string path = @".\data.txt";
StreamReader sr = new StreamReader(path);
string line;
this.kvant = int.Parse(sr.ReadLine());
Regex regex = new Regex(@"\w\,\d+\,\d+\,\d+");
for (int i = 0; i < N; i++)
{
if ((line = sr.ReadLine()) != null)
{
Match match = regex.Match(line);
if (match.Success)
{
string[] arr = match.Value.Split(new char[] { ',' });
this.id[this.count] = this.count;
this.name[this.count] = arr[0];
this.begin_time[this.count] = int.Parse(arr[1]);
this.priority[this.count] = int.Parse(arr[2]);
this.process_time[this.count] = int.Parse(arr[3]);
this.count++;
}
else
{
MessageBox.Show("Неправильные данные на входе.\nПрограмма продолжит свою работу без указанных неверно данных.", "Ошибка");
}
}
}
sr.Close();
for (int i = 0; i < this.count; i++)
{
int razn = this.begin_time[i] - this.sum_time;
if (razn > 0)
{
this.sum_time += razn;
}
this.sum_time += this.process_time[i];
}
this.sum_time *= this.kvant;
}
private void increment()
{
this.cur_time += this.kvant;
this.refreshLibTime();
}
private void refreshLibTime()
{
25
this.lib_time += this.kvant;
int minutes = this.lib_time / 60;
int seconds = this.lib_time % 60;
label2.Text = minutes.ToString() + ":" + ((seconds < 10) ? ("0" + seconds.ToString()) : seconds.ToString());
}
protected void drawAxes()
{
Graphics g = pictureBox1.CreateGraphics();
Pen pen = new Pen(Brushes.Black, 2);
g.FillRectangle(new SolidBrush(SystemColors.Control), 0, 0, pictureBox1.Width, pictureBox1.Height);
g.DrawLine(pen, new Point(30, 30), new Point(30, pictureBox1.Height - 30));
g.DrawLine(pen, new Point(30, pictureBox1.Height - 30), new Point(pictureBox1.Width - 30, pictureBox1.Height - 30));
g.DrawLine(pen, new Point(20, 50), new Point(30, 30));
g.DrawLine(pen, new Point(39, 50), new Point(29, 30));
g.DrawLine(pen, new Point(pictureBox1.Width - 50, pictureBox1.Height - 21), new Point(pictureBox1.Width - 30, pictureBox1.Height - 31));
g.DrawLine(pen, new Point(pictureBox1.Width - 50, pictureBox1.Height - 40), new Point(pictureBox1.Width - 30, pictureBox1.Height - 30));
g.DrawString("Процессы", new Font("Tahoma", 25), new SolidBrush(Color.Gray), new PointF(45, 10));
g.DrawString("t, c", new Font("Tahoma", 30), new SolidBrush(Color.Gray), new PointF(pictureBox1.Width - 75, pictureBox1.Height - 90));
int height_axisY = pictureBox1.Height - 90;
float marginY = (float)height_axisY / (float)this.count;
for (int i = 1; i <= this.count; i++)
{
g.DrawLine(pen, new Point(25, pictureBox1.Height - 30 - i * (int)marginY), new Point(30, pictureBox1.Height - 30 - i * (int)marginY));
g.DrawString(this.name[i - 1], new Font("Tahoma", 15), new SolidBrush(Color.Black), new PointF(5, pictureBox1.Height - 45 - i * (int)marginY));
}
int height_axisX = pictureBox1.Width - 90;
int margins_amount = (int)((float)this.sum_time / this.kvant) + 1;
float marginX = (float)height_axisX / (float)(margins_amount);
for (int i = 0; i <= margins_amount; i++)
{
g.DrawLine(pen, new Point(30 + (int)marginX * i, pictureBox1.Height - 30), new Point(30 + (int)marginX * i, pictureBox1.Height - 27));
g.DrawString((this.kvant * i).ToString(), new Font("Tahoma", 8), new SolidBrush(Color.Black), new PointF(30 + (int)marginX * i - 5, pictureBox1.Height - 27));
}
}
private void drawLegend()
{
Graphics gL = pictureBox2.CreateGraphics();
Pen pen = new Pen(Brushes.Red, 3);
gL.DrawString("Процесс в режиме готовности", new Font("Tahoma", 8), new SolidBrush(Color.Black), new PointF(10, 8));
gL.DrawLine(pen, new Point(170, 15), new Point(250, 15));
gL.DrawString("Процесс выполняется", new Font("Tahoma", 8), new SolidBrush(Color.Black), new PointF(10, 27));
pen.Color = Color.LightGreen;
gL.DrawLine(pen, new Point(170, 34), new Point(250, 34));
}
private void sortQueue()
26
{
int temp;
for (int i = 0; i < this.queue.Count; i++)
{
for (int j = this.queue.Count - 1; j > i; j--)
{
if (this.priority[(int)this.queue[j]] < this.priority[(int)this.queue[j - 1]])
{
temp = (int)this.queue[j];
this.queue[j] = this.queue[j - 1];
this.queue[j - 1] = temp;
}
}
}
}
private void checkPop()
{
if ((this.current_proc == -1 || this.current_proc_time >= this.process_time[this.current_proc]))
{
if (this.queue.Count != 0)
{
if (this.current_proc != -1)
{
this.procFulfilled();
}
this.current_proc = (int)this.queue[0];
this.current_proc_time = this.kvant;
this.queue.RemoveAt(0);
}
else
{
this.procFulfilled();
this.current_proc = -1;
}
}
else
{
if (this.current_proc != -1)
{
this.current_proc_time += this.kvant;
}
}
}
private void procFulfilled()
{
Graphics g = pictureBox1.CreateGraphics();
int height_axisX = pictureBox1.Width - 90;
int margins_amount = (int)((float)this.sum_time / this.kvant) + 1;
float marginX = (float)height_axisX / (float)(margins_amount);
int height_axisY = pictureBox1.Height - 90;
float marginY = (float)height_axisY / (float)this.count;
Pen pen = new Pen(Brushes.Black, 1);
pen.DashStyle = DashStyle.Dash;
g.DrawLine(pen, new Point(30 + (int)marginX * this.cur_time / this.kvant, pictureBox1.Height - 30), new Point(30 + (int)marginX * this.cur_time / this.kvant, pictureBox1.Height - 30 - (this.current_proc + 1) * (int)marginY));
}
27
private void refreshQueue()
{
for (int i = 0; i < this.count; i++)
{
if (this.cur_time >= this.begin_time[i])
{
bool flag = false;
for (int j = 0; j < this.lost_queue.Count; j++)
{
if ((int)this.lost_queue[j] == this.id[i])
{
flag = true;
}
}
if (!flag)
{
this.queue.Add(this.id[i]);
this.lost_queue.Add(this.id[i]);
Graphics g = pictureBox1.CreateGraphics();
int height_axisX = pictureBox1.Width - 90;
int margins_amount = (int)((float)this.sum_time / this.kvant) + 1;
float marginX = (float)height_axisX / (float)(margins_amount);
int height_axisY = pictureBox1.Height - 90;
float marginY = (float)height_axisY / (float)this.count;
Pen pen = new Pen(Brushes.Black, 1);
pen.DashStyle = DashStyle.Dash;
if (this.cur_time != 0)
{
g.DrawLine(pen, new Point(30 + (int)marginX * this.cur_time / this.kvant, pictureBox1.Height - 30), new Point(30 + (int)marginX * this.cur_time / this.kvant, pictureBox1.Height - 30 - (i + 1) * (int)marginY));
g.DrawString(this.name[i], new Font("Tahoma", 8), new SolidBrush(Color.Black), new PointF(30 + (int)marginX * this.cur_time / this.kvant - 10, pictureBox1.Height - 30 - (i + 1) * (int)marginY - 15));
}
}
}
}
this.sortQueue();
this.checkPop();
}
private void drawStateProcesses()
{
Graphics g = pictureBox1.CreateGraphics();
int height_axisX = pictureBox1.Width - 90;
int margins_amount = (int)((float)this.sum_time / this.kvant) + 1;
float marginX = (float)height_axisX / (float)(margins_amount);
int height_axisY = pictureBox1.Height - 90;
float marginY = (float)height_axisY / (float)this.count;
Pen pen = new Pen(Brushes.LightGray, 1);
pen.DashStyle = DashStyle.Dash;
for (int i = 1; i <= this.count; i++)
{
28
g.DrawLine(pen, new Point(30 + (int)marginX * (this.cur_time / this.kvant) - (int)marginX, pictureBox1.Height - 30 - i * (int)marginY), new Point(30 + (int)marginX * (this.cur_time / this.kvant), pictureBox1.Height - 30 - i * (int)marginY));
}
pen.Color = Color.Red;
pen.DashStyle = DashStyle.Solid;
pen.Width = 3;
for (int i = 0; i < this.queue.Count; i++)
{
g.DrawLine(pen, new Point(30 + (int)marginX * (this.cur_time / this.kvant) - (int)marginX, pictureBox1.Height - 30 - ((int)this.queue[i] + 1) * (int)marginY), new Point(30 + (int)marginX * (this.cur_time / this.kvant), pictureBox1.Height - 30 - ((int)this.queue[i] + 1) * (int)marginY));
}
pen.Color = Color.LightGreen;
pen.DashStyle = DashStyle.Solid;
pen.Width = 5;
if (this.current_proc != -1)
{
g.DrawLine(pen, new Point(30 + (int)marginX * (this.cur_time / this.kvant) - (int)marginX, pictureBox1.Height - 30 - (this.current_proc + 1) * (int)marginY), new Point(30 + (int)marginX * (this.cur_time / this.kvant), pictureBox1.Height - 30 - (this.current_proc + 1) * (int)marginY));
}
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
label5.Text = "1 тик в " + (trackBar1.Value * 10).ToString() + " мс";
timer1.Interval = trackBar1.Value * 10 * ((this.kvant != 0) ? this.kvant : 1);
}
}
}