У меня есть несколько приложений форм, которые полагаются на рабочие потоки для выполнения всей обработки.Они общаются с внешним приложением, которое в некоторых случаях опирается на имитацию пользовательского интерфейса (функциональность копирования / вставки).
В каждом случае у меня есть RichTextBox в форме, чтобы обеспечить обратную связь с пользователем во время выполнения - что необходимобыть асинхронным, чтобы текстовое поле могло обновляться в режиме реального времени.(отказ от ответственности: это было мое первое погружение в мир потоковых и асинхронных процессов, часть обратной связи работает по крайней мере!)
У меня есть класс "AppTrack", который используется для мониторинга всех этих приложений на предмет использования,отчетность и лучшая обработка исключений.В нем есть 2 функции (показанные ниже), которые я использую для «безопасного» запуска рабочих потоков, а также включения / выключения определенных элементов управления формой для предотвращения дальнейшего взаимодействия с пользователем.
public static void DoInSafeThread(Action ActualThreadFunction, List<Control> FormControls = null)
{
System.Action<System.Exception> exception = null;
Thread thread = new Thread(
() => AppTrack.SafeExecute(() => ActualThreadFunction(), exception, FormControls)
);
thread.IsBackground = true;
thread.Start();
}
private static void SafeExecute(Action ActualThreadFunction, Action<Exception> handler, List<Control> FormControls)
{
try
{
DisableControls(FormControls);
ActualThreadFunction.Invoke();
EnableControls(FormControls);
}
catch (Exception ex)
{
Handler(ex);
}
}
Это вызывает у меня большойпроблема, если есть список вещей для обработки, как фрагмент ниже.Он запустит новый рабочий поток для каждого, а характер интерфейса с внешним приложением означает, что процессы вмешиваются и дают плохие результаты / ошибки.
foreach (IOccurrences s in sel)
{
AppTrack.DoInSafeThread(delegate()
{
CableChecking.CheckCables((IOccurrences)s, rtbLog, CableData, materials);
}, FormControls);
}
Мысли о решении
Имейте единственную нить, используемую в моем классе "AppTrack".Назначьте ему новую операцию после завершения предыдущей или поставьте в очередь их для выполнения по порядку и, в конечном итоге, сообщите потоку графического интерфейса о том, что все задания завершены.Но, пытаясь реализовать это, я попал в кирпичную стену ... Это даже правильный подход?
Я надеялся найти такие вещи, как thread.BindNewAction, но, по-видимому, это неправильно ...