private void ThreadRegistration(Object obj) { InfectiousDepartmentForm form = (InfectiousDepartmentForm)obj; String str; // Сигнализируем о начале работы регистратуры str = "Регистратура начала работу в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); Random random = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); // Выполняем, пока не получена команда завершения while (!form._stop) { int delay = Convert.ToInt32(random.NextDouble() * 1000 * form._maxRegistrationTime); bool isInfected = (delay % 2 == 0) ? false : true; Patient patient = new Patient(this, isInfected); str = "---- Поступил " + ((isInfected) ? "инфицированный" : "здоровый") + " пациент " + patient.Number.ToString() + " в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); // И помещаем пациента в общую очередь lock (form._registrationQueue) { form._registrationQueue.Add(patient); // Если пациент инфицирован, увеличим счетчик if (patient.IsInfected) { form._infected++; } } form.Invoke(PatientEntryRegistration, new Object[] { patient }); // Ждем следующего пациента Thread.Sleep(delay); } // Сигнализируем о завершении работы регистратуры str = "Регистратура закончила работу в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); // Удаляем ссылку на поток из списка form.Invoke(form.RemoveCompletedThread, new Object[] { form._registrationThread }); }
private void ThreadObservationRoom(Object obj) { InfectiousDepartmentForm form = (InfectiousDepartmentForm)obj; Patient patient; String str; bool isInfected = false; bool isExit = false; // Сигнализируем о начале работы смотровой комнаты str = "Смотровая комната начала работу в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); // Основной цикл потока while (!isExit) { lock (form._registrationQueue) { lock (form._observationRoomQueue) { // Если нужно завершить работу, завершим if (form._stop && form._registrationQueue.Count == 0 && form._observationRoomQueue.Count == 0) { isExit = true; } else { // Если очередь регистратуры не пуста if (form._registrationQueue.Count != 0) { // Помещаем пациентов в смотровую комнату if (form._observationRoomQueue.Count == 0) { // Определяем, здоровых или инфицированных пациентов будем принимать по первому в очереди patient = form._registrationQueue[0]; // Блокируем доступ к объекту пациента lock (patient) { form._registrationQueue.Remove(patient); isInfected = patient.IsInfected; // Если пациент инфицирован, уменьшим счетчик if (patient.IsInfected) { form._infected--; } // Пациент перемещается в смотровую комнату form.Invoke(PatientEntryObservationRoom, new Object[] { patient }); form._observationRoomQueue.Add(patient); str = "---- Пациент " + patient.Number.ToString() + " перешел в смотровую комнату в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); } } // Добавляем либо здоровых либо инфицированных пациентов, в зависимости от того, // какие уже есть в очереди int i = 0; while (form._observationRoomQueue.Count < form._observationRoomCapacity) { // Если в очереди регистратуры нет таких пациентов, выйдем из цикла if (i == form._registrationQueue.Count) { break; } // Смотрим, что за пациент в очереди patient = form._registrationQueue[i]; lock (patient) { if (patient.IsInfected == isInfected) { form._registrationQueue.Remove(patient); // Если пациент инфицирован, уменьшим счетчик if (patient.IsInfected) { form._infected--; } // Пациент перемещается в смотровую комнату form.Invoke(PatientEntryObservationRoom, new Object[] { patient }); form._observationRoomQueue.Add(patient); str = "---- Пациент " + patient.Number.ToString() + " перешел в смотровую комнату в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); } else { // Увеличим номер пациента в очереди i++; } } } } } } } // Если нет команды завершить работу if (!isExit) { // Ждем новых пацинтов Thread.Sleep(1000); } } str = "Смотровая комната закончила работу в " + DateTime.Now.ToString() + "\n"; form.Invoke(form.ToProtocolDelegate, new Object[] { str }); // Удаляем ссылку на поток из списка form.Invoke(form.RemoveCompletedThread, new Object[] { form._observationRoomThread }); }
public void Run() { Random random = new Random((int)DateTime.Now.Ticks & 0x0000FFFF); DateTime doctorTime1 = DateTime.Now; DateTime doctorTime2 = DateTime.Now; DateTime consultantTime1 = DateTime.Now; DateTime consultantTime2 = DateTime.Now; String str; TimerCallback callback = new TimerCallback(SetInfected); System.Threading.Timer timer = new System.Threading.Timer(callback, this, _form._infectionTime * 1000, Timeout.Infinite); Thread.Sleep(1000); // Ждем перевода в очередь смотровой комнаты _restart.WaitOne(); timer.Dispose(); // Получаем время приема пациента врачом и признак необходимости консультации int receiptTime = random.Next(1, _form._maxReceiptTime); bool isConsultation = (receiptTime % 3 == 0) ? true : false; // Пациент направляется к врачу _form._doctorsAvailable.WaitOne(); lock (_form._freeDoctors) { _doctor = _form._freeDoctors.Dequeue(); _doctor.Patient = this; } doctorTime1 = DateTime.Now; str = "---> Врач " + _doctor.Number.ToString() + " начал прием пациента " + _number.ToString() + " в " + doctorTime1.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); // При необходимости консультации if (isConsultation) { str = "---> Врачу " + _doctor.Number.ToString() + " при приеме пациента " + _number.ToString() + " потребовалась консультация в " + DateTime.Now.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); // Выбираем консультанта, ждем некоторое время if (_form._doctorsAvailable.WaitOne(_form._maxReceiptTime * 1000)) { // Есть доступный консультант lock (_form._freeDoctors) { _consultant = _form._freeDoctors.Dequeue(); _consultant.Patient = this; } consultantTime1 = DateTime.Now; str = "<--> Консультант " + _consultant.Number.ToString() + " присоединился к врачу " + _doctor.Number.ToString() + " при приеме пациента " + _number.ToString() + " в " + consultantTime1.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); } else { // Врач сам разобрался с диагнозом str = "---> Врач " + _doctor.Number.ToString() + " сам определился с диагнозом пациента " + _number.ToString() + " в " + DateTime.Now.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); } } // Прием у врача Thread.Sleep(receiptTime * 1000); // Если был приглашен консультант, то он завершил прием пациента if (isConsultation && _consultant != null) { consultantTime2 = DateTime.Now; _consultant.Working(consultantTime2 - consultantTime1); str = "<--> Консультант " + _consultant.Number.ToString() + " завершил прием пациента " + _number.ToString() + " в " + consultantTime2.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); lock (_form._freeDoctors) { _consultant.Patient = null; _form._freeDoctors.Enqueue(_consultant); _consultant = null; } _form._doctorsAvailable.Release(); } // Врач завершил прием пациента doctorTime2 = DateTime.Now; _doctor.Working(doctorTime2 - doctorTime1); str = "---> Врач " + _doctor.Number.ToString() + " завершил прием пациента " + _number.ToString() + " в " + doctorTime2.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); lock (_form._freeDoctors) { _doctor.Patient = null; _form._freeDoctors.Enqueue(_doctor); _doctor = null; } _form._doctorsAvailable.Release(); // Пациент покидает смотровую комнату str = "---- Пациент " + _number.ToString() + " покинул смотровую комнату в " + DateTime.Now.ToString() + "\n"; _form.Invoke(_form.ToProtocolDelegate, new Object[] { str }); // Удаляем пациента из списка находящихся в смотровой комнате lock (_form._observationRoomQueue) { _form._observationRoomQueue.Remove(this); } // timer.Dispose(); // Сигнализация о завершении потока объекта пациента _form.Invoke(_form.RemoveCompletedThread, new Object[] { _thread }); }