Trink писал(а):Я лишь написал что в потоках в место форм VB, создаются окна непосредственным вызовом winapi. Почему? Предполагаю что формы не такие уж и многопоточные.
Потому что речь идёт о примере с каким-то трюкачеством. Трюкачества обсуждать не хочется, хотя это одна из моих любимых тем.
Trink писал(а):Зачем это нужно если почти во всех VB прогах только один поток?
Затем,
что поток может быть не один. Никто не запрещает иметь их много.
Но во-первых, нужно зарубить себе на носу, что если ты пишешь на VB, то
нельзя (или по крайней мере —
чревато) пользоваться функций
CreateThread. Это не какой-то уникальный случай. Такая же история с Си.
Если ты пишешь многопоточную программу на Си под Windows, и пользуешься сишным рантаймом, то ты тоже не имеешь права вызывать CreateThread. Вместо этого ты должен вызывать
_beginthread или
_beginthreadex. Только так сишный рантайм имеет шанс самоинициализироваться для нового потока.
Тебя не смущает это? Тебя не возмущает, то что Си устроен и живёт по таким правилам.
Эти правила достаточно обоснованы. И в VB ситуация аналогичная. Нельзя просто создавать поток, используя CreateThread, передавая управление на свой код, не позаботившись перед этим об инициализации рантайма.
Окей.
Есть ли аналог сишного
_beginthread или
_beginthreadex в VB-райнтайме? Ну, во-первых, VB-рантайм написан на Си/Си++, поэтому сишный рантайм вшит в него (статически влинкован). Поэтому внутри VB-рантайма тоже живёт функция _beginthreadex. Обращение к ней идёт из
CVBThreadAction::InitExeThrd. А к ней идёт обращение из
CThreadPool::_InitThread.
Напрямую вызвать что-нибудь из этого для создания нового потока — такую возможность создатели VB сознательно исключили наравне с возможность выделять память вручную.
Тем не менее, можно порождать объекты, для которых будут порождаться новые потоки. Таким образом, создав VB-класс
CWorkerThread, можно получать со своей стороны (со стороны главного потока) объект, олицетворяющий другой поток. Имея у этого класса методы типа
PutJobIntoQueue, можно из главного потока посылать какую-то работу в очередь другого потока. И тот будет делать. Тот будет делать, а потом дёргать у этого класса CWorkerThread событие JobCompletion, для того, чтобы уведомлять главный поток о том, что работа закончилась (и сообщать какой-то результат).
Единственное недоразумение: режим, при котором под каждый новый объект создаётся новый поток — возможен только при типе проекта, равном
ActiveX EXE. В стандартном проекте дропдаун «Threading Model» в свойствах проекта залочен. Недоразумение. Жалко. Не не катастрофа. Проект типа
ActiveX EXE ничем не хуже проекта типа
Standard EXE.
У меня таким образом написан многопоточный сервер на VB, задействованный в одном крупном проекте. Я написал его за две недели как быстрый черновик, чтобы найти проблемы в архитектуре и через некоторое время переписать этот же сервер в виде сервиса на сях. Но проблем не нашлось, а сервер на VB всем понравилось, поэтому люди, которые финансируют разработку, даже отказались финансировать переписывание сервера с VB на Си. Так и работает этот сервер уже больше года, обрабатывая 300 тысяч запросов в сутки. Стабильно и гладко. Мы уже забыли о нём и воспринимаем его безупречную работу как что-то само собой разумеющееся и незыблемое.
_____________
Кроме того, значительную долю пирога применения VB составляет написание DLL-библиотек и OCX-контролов. Поэтому твой вопрос
Trink писал(а):Зачем это нужно если почти во всех VB прогах только один поток?
тут звучит глупо.
Затем, что на VB ты можешь писать классы и юзер-контролы, которые будут
успешно работать в рамках
других многопоточных приложений. Чужих. Сишных. Дейльфишных. VB-шных. Каких угодно.
Очень классно и удобно писать на VB экстеншоны для IE или проводника (файлового). Причём даже для новых IE они пишутся до сих пор так же, как для 5–6-го. Проводник и IE — многопоточные приложения, но потокобезопасный рантайм обеспечивает контролам и просто DLL-шным классам нормальную работу.
Так поддерживает ли VB многопоточность? Единственное, чего не поддерживает VB: это создания потока напрямую, насильно, без создания объекта. Но для этого я делал кирпич. Там вот процентов 10 доделать, и тогда VB будет и это поддерживать.