Какие недостатки в коде/ваше мнения о данном коде?
Насколько я понял это парсер страниц какого то сайта с поддержкой нескольких прокси серверов, спарсенное складируется в БД, особых костылей в коде не вижу, все достаточно просто и относительно понятно. Из того что заметил странно выглядит обилие репортов от воркера, даже в тех местах что отрабатываются за доли секунды, если по репорту идет обновление UI потока это может замедлить работу.  Для читабельности убрал бы лишние комменты (старый код) и лишние переносы строк (пустые строки). Еще отдельный момент обилие messagebox, в работе вероятно нужно постоянно тыкать "ОК" чтобы все продолжало работать, я бы это заменил на вывод в лог или в отдельное поле в UI, кому надо тот сам посмотрит, рабочее приложение в этом обычно не нуждается.
Совет по общей структуре: в классе формы многовато данных. Понятно что с нее вы начинали все писать и из нее все вызывается, но время от времени нужно выделять группы данных/методов и выносить в отдельные классы или модули (в случае шарпа - это т.н. "статические" классы). Я по вашему коду разбил бы примерно так:
- хелперы для загрузки данных через прокси (и их автоматического переключения в случае ошибки - я правильно понял?): можно вынести в отдельный УмныйЗагрузчик, который заберет в себя всю логику пробивания к данным - перебор юзер-агентов, сбор статистики и т.д. Из этого умного загрузчика должны торчать: простой метод для загрузки нужного урла, простой метод для получения статистики, пусть даже текстом. На форме останется лишь присовение этой статистики 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-документацию, раз уж делаете комментарии к методам
- по возможности привыкайте пользоваться английским - довольно мало команд разработчиков могут себе позволить использование родного языка в коде.
Для начала достаточно. Прежде чем заморачиваться паттернами, ощутите на нескольких примерах как вообще пользоваться ОО-языком, что он вам дает и что требует от вас.