/// <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> /// Метод 1-го потока производителя /// </summary> private void Producer1() { Assembly asm = LoadingPlugin("ClassLibrary1.dll"); if (asm == null) // Если не загрузилась DLL { DisplayedErrorLoad(1); // Отображаем ошибку загрузки на форме 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(); // Используем Semafor Monitor.Enter(Qe); // Используем Monitor if (Qe.Count < 20) // Если очередь не заполнена { foreach (MethodInfo m in mi) { if (m.Name.CompareTo("CheckingForDivisibilityByTwo") == 0) // Если имя метода "CheckingForDivisibilityByTwo" { // Массив параметров вызываемого из dll метода object[] args = new object[1]; try { // Первый(и единственный) параметр args[0] = Convert.ToInt32(maskedTextBox1.Text); } catch (Exception) { // Если к label нельзя подключиться из этого потока // используем BeginInvoke и подключаемся // Отображаем ошибку в label if (ResultPerformingForBaseTwo.InvokeRequired) { ResultPerformingForBaseTwo.BeginInvoke(new Action <string>((ts) => ResultPerformingForBaseTwo.Text = ts), "<Error conversion>"); } continue; } // Создаём экземпляр структуры EntryQueue tmp; // Заносим номер метода в структуру tmp.NumberReference = 1; // Выполнение метода из dll и занесение результата в экземпляр структуры tmp.ResultOperation = (bool)m.Invoke(reflectOb, args); // Занесение экземпляра структуры в очередь Qe.Enqueue(tmp); } if (m.Name.CompareTo("CheckingForDivisibilityByThree") == 0) // Если имя метода "CheckingForDivisibilityByThree" { // Массив параметров вызываемого из dll метода object[] args1 = new object[1]; try { // Первый(и единственный) параметр args1[0] = Convert.ToInt32(maskedTextBox2.Text); } catch (Exception) { // Если к label нельзя подключиться из этого потока // используем BeginInvoke и подключаемся // Отображаем ошибку в label if (ResultPerformingForBaseThree.InvokeRequired) { ResultPerformingForBaseThree.BeginInvoke( new Action <string>((ts) => ResultPerformingForBaseThree.Text = ts), "<Error conversion>"); } continue; } // Создаём экземпляр структуры EntryQueue tmp; // Заносим номер метода в структуру tmp.NumberReference = 2; // Выполнение метода из dll и занесение результата в экземпляр структуры tmp.ResultOperation = (bool)m.Invoke(reflectOb, args1); // Занесение экземпляра структуры в очередь Qe.Enqueue(tmp); } } } else { Thread.Sleep(1); // На 1 мс приостанавливаем поток } Monitor.Exit(Qe); // Выходим из Монитора s1.Release(1); // Освобождаем Semafor } }