У меня есть форма Windows, которая отображает любое количество записей: эти наборы данных описывают объекты, для которых необходимо выполнить вычисления.
Для большинства наборов данных эти вычисления можно выполнить без изменения объектов.
Пока выполняются эти вычисления — я называю эту часть работы Процессом А — должны обрабатываться объекты, принадлежащие остальным наборам данных. Только после этого можно будет провести расчеты для этих оставшихся наборов данных — я называю эту часть работы Процессом Б.
Вычисления для A и B выполняются экземплярами другой формы, которые обращаются к C++ DLL.
После завершения расчета процесса создается файл для A и B соответственно, существование которого указывает на окончание расчета для этого процесса.
Как A, так и B могут занять больше времени, чем другие процессы, поскольку объем наборов данных в каждом из них может сильно различаться. Только после завершения обоих процессов можно объединить результаты их вычислений.
Как оптимально спроектировать обе задачи?
Я использую C# и .Net Framework 4.5.2. Чтобы уточнить:

Теодор Зулиас, спасибо за интерес к моему вопросу. Чтобы объяснить больше: Оба потока должны обрабатывать структурно идентичный список (объектов) в форме:
публичный класс ListEl: IComparable { общедоступная строка objName; //Имя объекта, являющегося предметом вычислений с помощью C++ DLL общедоступные значения double[]; } Рассчитываемые значения[] частично зависят друг от друга. Расчеты выполняются путем вызова вычислений класса:
с использованием C++-DLL; расчеты классов { public static int Calc (ListEl s, строка saveName) { пытаться { если (C++-DLL.calc(saveName) == 1) { errorMsg = "Ошибка!\n"; вернуть -1; } } поймать (Исключение ex) { errorMsg = ex.Message; вернуть -1; } } public static void saveResults(ListEl s, строковое имя файла) { } } Форма вызова:
публичный частичный класс SelectObjects: Форма { общедоступный класс ListEl: IComparable { общедоступная строка objName; //Имя объекта, являющегося предметом вычислений с помощью C++ DLL общедоступные значения double[]; //результаты вычислений с C++ DLL } вызов частной строки = ""; публичная форма SelectObjects() { ИнициализироватьКомпонент(); listA = новый список(); listB = новый список(); заполнитьСписок(); заполнитьСписокB(); } частная кнопка voidA_Click (отправитель объекта, EventArgs e) { FrmCalc frmA = новый FrmCalc() { списокА = этот.списокА, вызов = "А"; }; frmA.Показать(); } частная кнопка voidB_Click (отправитель объекта, EventArgs e) { FrmCalc frmB = новый FrmCalc() { списокБ = этот.списокБ, вызов = "Б"; }; frmB.Показать(); } общественная пустота mergeResults() { // считываем результаты A и B в список } } Форма вызывается дважды:
публичный частичный класс FrmCalc: Форма { общедоступный класс ListEl: IComparable { общедоступная строка objName; общедоступные значения double[]; } частная строка _calling = ""; вызов публичной строки { получить {вернуться _calling; } установить { _calling = значение; } } Threading.Thread threadA; Threading.Thread threadB; общедоступный FrmCalc() { ИнициализироватьКомпонент(); listA = новый список(); listB = новый список(); } частная пустота FrmCalc_Shown (отправитель объекта, EventArgs e) { если (вызов == "A") { ThreadA = новый поток (новый ThreadStart (workA)); ThreadA.Priority = ThreadPriority.AboveNormal; ThreadA.Start(); } иначе, если (вызов == "B") { threadB = новый поток (новый ThreadStart (workB)); потокB.Priority = ThreadPriority.AboveNormal; потокB.Start(); } } публичная недействительная работаA() { foreach (ListEl в спискеA) { вычисления.calc(s, saveName); расчеты.saveResults(s, fileResultsA); } } публичная недействительная работаB() { foreach (ListEl в списке B) { вычисления.calc(s, saveName); расчеты.saveResults(s, fileResultsB); } } } Если FrmCalc вызывается дважды, как показано здесь, вычисления в классе C++ DLL неизбежно приведут к конфликтам. Как мы можем предотвратить это? Возможно, вызывая две копии C++ DLL в вычислениях классов?