/// <summary> /// Метод потока потребителя /// </summary> public void Consumer() { EntryQueue tmp; while (NeedWorksStream()) // Выполняем пока не произойдёт событие выхода { s2.WaitOne(); // Входим в семафор if (Qe.Count < 1) // Если отсутствуют результаты в очереди { Thread.Sleep(1); // На 1 мс приостанавливаем поток } else { // Извлекаем результат из очереди в буферную структуру tmp = (EntryQueue)Qe.Dequeue(); switch (tmp.NumberReference) { case 1: // Если к label нельзя подключиться из этого потока // используем BeginInvoke и подключаемся // Отображаем результат из очереди на форме (в label) if (ResultPerformingForBaseTwo.InvokeRequired) { ResultPerformingForBaseTwo.BeginInvoke(new Action <string>((ts) => ResultPerformingForBaseTwo.Text = ts), tmp.ResultOperation.ToString()); } break; case 2: if (ResultPerformingForBaseThree.InvokeRequired) { ResultPerformingForBaseThree.BeginInvoke(new Action <string>((ts2) => ResultPerformingForBaseThree.Text = ts2), tmp.ResultOperation.ToString()); } break; case 3: if (ResultPerformingForBaseFive.InvokeRequired) { ResultPerformingForBaseFive.BeginInvoke(new Action <string>((ts3) => ResultPerformingForBaseFive.Text = ts3), tmp.ResultOperation.ToString()); } break; case 4: if (ResultPerformingForBaseTen.InvokeRequired) { ResultPerformingForBaseTen.BeginInvoke(new Action <string>((ts4) => ResultPerformingForBaseTen.Text = ts4), tmp.ResultOperation.ToString()); } break; } } s2.Release(); // Выходим из семафора } }
/// <summary> /// Метод 2-го потока производителя /// </summary> private void Producer2() { Assembly asm = LoadingPlugin("ClassLibrary2.dll"); if (asm == null) { DisplayedErrorLoad(2); // Отображаем ошибку загрузки на форме return; } Type[] alltypes = asm.GetTypes(); ConstructorInfo[] ci = alltypes[0].GetConstructors(); object reflectOb = ci[0].Invoke(null); MethodInfo[] mi = alltypes[0].GetMethods( BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); while (NeedWorksStream()) // Выполняем пока не произойдёт событие выхода { s1.WaitOne(); Monitor.Enter(Qe); // Используем Monitor if (Qe.Count < 20) // Если очередь не заполнена { foreach (MethodInfo m in mi) { if (m.Name.CompareTo("CheckingForDivisibilityByFive") == 0) // Если имя метода "CheckingForDivisibilityByFive" { object[] args = new object[1]; try { args[0] = Convert.ToInt32(maskedTextBox3.Text); } catch (Exception) { if (ResultPerformingForBaseFive.InvokeRequired) { ResultPerformingForBaseFive.BeginInvoke( new Action <string>((ts) => ResultPerformingForBaseFive.Text = ts), "<Error conversion>"); } continue; } EntryQueue tmp; tmp.NumberReference = 3; tmp.ResultOperation = (bool)m.Invoke(reflectOb, args); Qe.Enqueue(tmp); } if (m.Name.CompareTo("CheckingForDivisibilityByTen") == 0) // Если имя метода "CheckingForDivisibilityByTen" { object[] args1 = new object[1]; try { args1[0] = Convert.ToInt32(maskedTextBox4.Text); } catch (Exception) { if (ResultPerformingForBaseTen.InvokeRequired) { ResultPerformingForBaseTen.BeginInvoke(new Action <string>((ts) => ResultPerformingForBaseTen.Text = ts), "<Error conversion>"); } continue; } EntryQueue tmp; tmp.NumberReference = 4; tmp.ResultOperation = (bool)m.Invoke(reflectOb, args1); Qe.Enqueue(tmp); } } } else { Thread.Sleep(1); // На 1 мс приостанавливаем поток } Monitor.Exit(Qe); s1.Release(1); } }