Совет по общей структуре: в классе формы многовато данных. Понятно что с нее вы начинали все писать и из нее все вызывается, но время от времени нужно выделять группы данных/методов и выносить в отдельные классы или модули (в случае шарпа - это т.н. "статические" классы). Я по вашему коду разбил бы примерно так:
- хелперы для загрузки данных через прокси (и их автоматического переключения в случае ошибки - я правильно понял?): можно вынести в отдельный УмныйЗагрузчик, который заберет в себя всю логику пробивания к данным - перебор юзер-агентов, сбор статистики и т.д. Из этого умного загрузчика должны торчать: простой метод для загрузки нужного урла, простой метод для получения статистики, пусть даже текстом. На форме останется лишь присовение этой статистики textBox.Text;
- парсер html-контента. Всю логику поиска данных на странице убрать в него.
- общий координатор работ - можно слить с предыдущим пунктом, можно выделить отдельно. Я бы убрал в него бэкграунд-воркеров, например, не обязательно им на форме торчать.
- код записи данных в базу тоже стоит вынести. Сделайте простейшие POCO-классы для данных, которые извлекаете из html, возращайте объекты из парсера и передавайте в сохранялку.
- ну и конечно сохранение настроек - это прекрасно отделится от всего остального также в отдельный класс.
Разумеется нужно разбивать не только код, но и данные вместе с ним - вы сами увидите, как все станет проще и читабельнее, когда public static int CounterProxy = 0;
будет в одном файле, а const string strWinState = "WindowState";
- в другом.
Ну а теперь по мелочам:
- не злоупотребляйте static-ами: статических данных в программе обычно немного, и это как правило объекты, с которых приложение начинает "жить" - и то лучше взять IoC-контейнер для этих целей. В вашем случае, когда вы разобьете код на классы, сами поймете что статики в таком количестве вам не нужны.
- ArrayList я уже давно не видел в коде, не знаю в каком учебнике вы его нашли. В вашем случае он тем более ни к чему. Используйте List<T>
и не извращайтесь вот так: Agent[CounterUserAgent].ToString();
- сразу давайте всему внятные имена, в т.ч. контролам. Это сейчас у вас button1 и button2, а завтра будет button42.
- используйте xml-документацию, раз уж делаете комментарии к методам
- по возможности привыкайте пользоваться английским - довольно мало команд разработчиков могут себе позволить использование родного языка в коде.
Для начала достаточно. Прежде чем заморачиваться паттернами, ощутите на нескольких примерах как вообще пользоваться ОО-языком, что он вам дает и что требует от вас.