powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Вызов функции с переменной в потоке.
25 сообщений из 30, страница 1 из 2
Вызов функции с переменной в потоке.
    #33308938
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1)Есть функция - Symma, вызываю в потоке так:
Код: plaintext
ThreadControl1.CreateNewThread AddressOf Symma, tpNormal, True
Всё проходит нормлаьно.
Добавляю в функцию входные переменные - Symma(a,b), при попытки изменить строку вызыва функции в потоке:
Код: plaintext
ThreadControl1.CreateNewThread AddressOf Symma(...), tpNormal, True
Начинает ругаться на всё что написано после "(...)": "Compile error: Syntax error"

Я так понял, что в функции которые вызываются в потоках не должно быть входных переменных. Если это так, то всё очень плохо. Может я не прав?

2) Если мне нужен результат выполненной функции в потоке, то пишу так:
Код: plaintext
1.
ThreadControl1.CreateNewThread AddressOf Symma, tpNormal, True 
z = Symma
, но при отладке видно(F8), что при присваивание "z" значение функции Symma, сама функция запускается ещё раз. В принципе это логично, пробывал написать так:
Код: plaintext
ThreadControl1.CreateNewThread AddressOf z = Symma, tpNormal, True
Cтудия сразу удаляет оператор "AddressOf", если при этом запустить то получаю: Application Error. Так же пробывал эксперементировать со скобками, но получал результат "Compile error: Syntax error".

Пришёл к выводу, что результат выполнения функции в потоке не льзя использовать. Может и тут я, что то не то делаю?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33309251
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. AddressOf употребляется только с именем функции без всяких параметров.
2. Понятия не имею что такое ThreadControl, однако апишная функция
Код: plaintext
Public Declare Function CreateThread Lib "kernel32" Alias "CreateThread" (lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
имеет параметр lpParameter, который можно передать в Sub Symma(lpParameter). Этим параметром может быть переменная пользовательского типа или указатель на объект.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33309533
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1)Без AddressOf работает вот так:
Код: plaintext
ThreadControl1.CreateNewThread Symma(a), tpNormal, False
В функцию Symma передаю параметр "a". Только пришлось поменять True на False.
Antonariy могли бы вы объяснить зачем нужен AddressOf и почему пришлось менять True на False?
Появились сомнения, что при отсутсвии AddressOf поток не запускается или это при False...

2)ThreadControl это -
Код: plaintext
Private ThreadControl1 As clsThreading
Бралось из примера Philipp Weidmann. И дальше работал по его примеру. Но всё равно не понимаю как получить результат выполнения функции в потоке. Пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Private ThreadControl1 As clsThreading
Private Sub Command1_Click()
    Dim mThreadPriority As ThreadPriority
    Dim mEnabled As Boolean
    Dim a As Integer
    Dim z As String
 
    mThreadPriority = tpNormal
    mEnabled = True
    
    'Create the thread
    a = ThreadControl1.CreateNewThread Symma( 4 ), tpNormal, False
    MsgBox a
End Sub
Выводимое значение "a" не соответствует действительности, выводится какоето левое число. А мне надо далее по программе использовать эти данные. :(
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33309605
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Добавь в CreateNewThread параметр lParam as Variant
2. В вызове CreateThread в параметр lpParameter подставь VarPtr(lParam)
3. Создай тип навроде
Код: plaintext
1.
2.
3.
4.
5.
Type MyType
    ParamIn1 As Integer
    ParamIn2 As String *  5 
    ParamOut1 As Integer
    ParamOut2 As String *  5 
End Type
Если нужно передавать строки, используй переменные фиксированной длины, чтобы не было гемороев с подсчетом размеров типа.
4. Процедуру Symma приведи к виду
Код: plaintext
1.
2.
3.
4.
5.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Sub Symma(lParam as Long)
Dim r as MyType
    CopyMemory r, lParam, Len(r)
'дальше делай с r что душе угодно
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33309763
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант с объектом:
В вызове CreateThread в параметр lpParameter подставь ObjPtr(lParam)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Sub Symma(lParam as Long)
Dim r as Class1
    Set r = ObjFromPtr(lParam)
    ....
End Sub

Private Function ObjFromPtr(lObjPtr As Long) As Object
    If lObjPtr <>  0  Then
        Dim LoTmp As Object
        CopyMemory LoTmp, lObjPtr,  4 
        Set ObjFromPtr = LoTmp
        CopyMemory LoTmp,  0 &,  4 
    End If
End Function
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311140
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чувстуется иду в тупик. Так опишу, что конкретно есть у меня и что пытаюсь сделать.
Есть функция, которая на входе получает имя БД, имя сервера и строку запроса, а на выходе(возвращает) рекордсет с данными
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Public Function CN(ByVal server As String, ByVal db As String, ByVal zapros As String) As Recordset
        Dim conn As ADODB.Connection
        Dim rs As ADODB.Recordset
        Dim constr As String
                
        On Error Resume Next
        
        Set rs = Nothing
        Set conn = New ADODB.Connection
        
        constr = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=" + db + ";Data Source=" + server + ";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=" + server + ";Use Encryption for Data=False;Tag with column collation when possible=False"
       
        conn.Open constr
             
        Set rs = New ADODB.Recordset
        Set rs.ActiveConnection = conn
               
        rs.CursorLocation = adUseClient
        rs.Open zapros, conn, adOpenStatic, adLockOptimistic, adCmdText
        
        Set rs.ActiveConnection = Nothing
        Set CN = rs
        OutputDebugString (rs.RecordCount)
End Function
С каждой БД системы надо слить данные, для этого создаю потоки по количеству серверов БД(для простоты = 2), в кажом потоке вызываю функцию CN со своими!!! входными переменными. Функция CN выполняется возвращая рекордсет. Далее уже работаю с данными этих рекордсетов
Мне надо запустить два потока к БД(или более потоков, зависит от количество БД в системе), получить рекордсеты и дальше работать с ними.
Вызывать потоки хотел так:
Код: plaintext
1.
ThreadControl1.CreateNewThread CN(servername1, dbname, zapros), tpNormal, False
ThreadControl2.CreateNewThread CN(servername2, dbname2, zapros), tpNormal, False
Так как я хотел нечерта не работает, сразу при компиляции орёт: Compile error: Type mismatch. Указывая на ".CreateNewThread".
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311238
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AzartЧувстуется иду в тупик.
Мне надо... получить рекордсеты и дальше работать с ними.А просто получить рекордсеты никак нельзя?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311259
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё можно, но у меня задача поставлена по другому.
К примеру есть 10 серверов БД. Если просто собирать данные по всем это будет долго, скажем на каждую БД по 1 сек, то 10*1=10 сек. А при параллельном сборе данных бдует 1сек+погрешность. Что гораздо быстрее. Вот поэтому я и мучаюсь с этими потоками.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311326
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Azartпри параллельном сборе данных бдует 1сек+погрешность. Что гораздо быстрее. Вот поэтому я и мучаюсь с этими потоками.Можно также помучаться с асинхронными запросами (есть положительный опыт).
Многопотоковость ( говорят , сам не проверял) в VB реализована неважно...
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311333
AzartВсё можно, но у меня задача поставлена по другому.
К примеру есть 10 серверов БД. Если просто собирать данные по всем это будет долго, скажем на каждую БД по 1 сек, то 10*1=10 сек. А при параллельном сборе данных бдует 1сек+погрешность. Что гораздо быстрее. Вот поэтому я и мучаюсь с этими потоками.
ага.
то исть в распоряжении наличия имеется 10-процессорный компуктер, на котором и будут разложены потоки.
а иначе с какого перепития вдруг економия возьмется?

мы честно заблуждаемся, или кого-то другого обмануть хотим?

да, и насчет рекордсетов-объектов в порожденных потоках.
я не спец, правда. но где-то слышал, что для того, чтобы оно работало в каждом потоке инициализировать ком-оле надо.
Однопоточный вб для себя при старте свово екзешника как юудто все, что ему надо инициализирует.
а в Вашем потоке почему Вы уверены, что за вВас это кто-то сделает?
(активикс екзе, конечно, для себя любимого все сделает, но это не то за что Вы боретесь, как будто... )

впрочем, вероятно, глупостей наговорил.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311352
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторМожно также помучаться с асинхронными запросами (есть положительный опыт). Не очень понимаю выгоду по времени в асинхронных запросах???
Про потоки, реализовать их можно и у меня получалось, но только с простыми вещами, но не как не с рекодсетами (
авторто исть в распоряжении наличия имеется 10-процессорный компуктер, на котором и будут разложены потоки.
ВЫ хотите сказать что многопоточность вообще не существует, как же народ её на С++ реализует???
авторчтобы оно работало в каждом потоке инициализировать ком-оле надо Сомнительно, нечего сказать не могу.
Короче понимаю, что затею плохая, придётся последовательно опрашивтаь все БД :(
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311387
авторВЫ хотите сказать что многопоточность вообще не существует, как же народ её на С++ реализует???
я хочу сказать, что многопоточность существует.
Если процессоров много - она может быть использована как один из механизмов реального распараллеливания работы, при котором можно получить ожидаемую Вами экономию.
Однако в программах народа на С++ (поскольку они почти всегда пишутся
для исполнения на однопроцессорных компуктерах) назначение многопоточности совсем другое. Она создает иллюзию быстродействия.
Позволяет обеспечить доступность программы для пользователя. Пользователь жмакаит кловишу и компуктер дзинь в ответ.
пользователь понимает, что компуктер работает. В однопоточном варианте дзинь в ответ не получится, пока не будет принят и обработан ожидаемый "рекордсет". все ворочается "одновременно". как бы. то есть последовательно получает свой квант времени, для выполнения малого куска работы. Для пользователя система доступна. Вам какой дурак сказал, что она при этом быстрее работает (в однопроцессорном варианте)?

Делайете что хотите - хотите плюйте ему в глаза. Хотите смейтесь.

Если Вы хотите обеспечить видимый отклик на действия пользователя своего приложения - многопоточность Вам в руки.
Если Вы собрались выиграть на этом производлительность - пардоньтесь - глупейшее проведение времени на однопроцессорной тачке.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311423
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AzartНе очень понимаю выгоду по времени в асинхронных запросах???
Если основное время тратится на выборку данных из БД в рекордсет, то клиент простаивает (что Вы и хотите устранить).
Время передачи строки запроса несопоставимо малО
со временем ожидания исполнения запроса.
Поэтому запросы можно рассылать на серверы БД последовательно,
а обрабатывать рекордсеты - по мере их поступления, т.е асинхронно.

Короче понимаю, что затею плохая, придётся последовательно опрашивтаь все БД :(Это - более быстрая в реализации схема.
Оптимизировать время выполнения надо тогда, когда это критично.
Из приведенной постановки задачи критичность ожидания не следует.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311445
Если Вы собрались выиграть на этом производлительность - пардоньтесь - глупейшее проведение времени на однопроцессорной тачке.

это верно, если речь идет исключительно о процессорном времени. но существуют и другие ресурсы: IO, запросы к серверам

постановка задачи была: "тяжелые запросы к нескольким серверам БД", а это уже не один процессор, не так ли?

согласем с мнением выше про использование асинхронных коннектов и запросов, ADO позволяет

есть еще метод создания ActiveX exe c соответствующей threding model, чтобы экземпляры создавались в своем потоке. я так делал для пула винсокетов

а винапишные треды лучше не использовать
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311481
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читал... много думал...
2 глупыйглупый: Однопоточность: пользователь кликнул и пошли дикие вычисления, пока они не закончаться форма ему будет не доступна. Многопоточность: пользователь кликнул и пошли дикие вычисления, НО форма ему доступна, значит он может запустить что то ещё, скажем другие вычисления. И по идеи они будут выполняться парраллельно.

авторИз приведенной постановки задачи критичность ожидания не следует. БД расскиданы далеко друг от друга и от клиентской машины. Скажем время получения ответа от первой БД = 10 сек, от второй 30 сек, от третьей 50 сек, следовательно пока я соберу данные со всех БД, время уйдёт 10+30+50=90 сек. Я надеялся, что при параллельности будет всего 50 сек!!!, самая боьшая задержка, т.к. все остальные успели уложиться. 90-50=40 сек вот на этот выигрыш я и расчитывал.
авторесть еще метод создания ActiveX exe c соответствующей threding model, чтобы экземпляры создавались в своем потоке. я так делал для пула винсокетов
Я пишу свою ДЛЛ, если можно использовать этот метод, то можно ссылочку...
авторсогласем с мнением выше про использование асинхронных коннектов и запросовКакой выигрыш во времени при асинхронных запросах?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311493
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Голенков Владимира винапишные треды лучше не использовать...прислушиваясь к Дэну Эпплману .
Поучительная статья.
Выразительный эпиграф:
Только потому, что Вы должны что-то делать, не всегда означает, что у Вас получится...
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311598
Какой выигрыш во времени при асинхронных запросах?

MSDN (Asynchronous Queries):

Another operation that can take some time to process is a query that retrieves results to the client. Running a query asynchronously allows control to be returned to the application before the query is completed. Implementation of this feature enables the user to continue or cancel a query that takes a long time to run. With this ability, during a long operation, developers can also do other operations—for example, display a progress dialog box or continue painting the form, or even start other asynchronous operations .


есть еще метод создания ActiveX exe c соответствующей threading model, чтобы экземпляры создавались в своем потоке

Threading Model

Thread per Object — Indicates that each instance of a class marked as Multiuse in the Instancing property will be created on a new and distinct thread. Each thread has a unique copy of all global variables and objects, and will not interfere with any other thread.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311623
2 Голенков Владимир
начсет "других ресурсов" - разумеется.
насчет не использовать - это будет долгий разовор. ну пусть - не использовать.

автор10+30+50=90 сек. Я надеялся, что при параллельности будет всего 50 сек!!!, самая боьшая задержка, т.к. все остальные успели уложиться. 90-50=40 сек вот на этот выигрыш я и расчитывал.

в конкретном случае - с такими запросами - может быть.
(изначально вы формулировали чуть иначе).
каждое из времен 10, 30, 50 раскладывается на время исполнения запроса, время передачи результата по сети и времени входящей обработки сетевых пакетов. при определенных их комбинациях асинхронное исполнение запросов
даст именно требуемое - общий результат уложится в 50 сек..

--------------------------
насчет threding model - вероятно речь о Thread Per Object в данном случае.
---------------------------
но, если есть 10 "идеальных" (в смысле времени отклика серверов, их сетевой равнноудаленности и т.д. ) запросов по 1 сек, то все может быть вовсе по другому.
Пусть 90% времени - это время обработки клиентом входного потока (сетевой слой + прикладной).
Пусть в "реальном" окружении, время исполнения запросов превращаются в 15 сек.
Тогда за счет многопоточных ухищрений Вы, возможно, сможете превратить 15 в 14, ну в 13. За пределы 10 выйти не получится. Ни о каких 1 сек при 10 потоках речь не пойдет. и время "идеального многопоточного" исполнения окажется гарантированно хуже времени идеального "последовательного исполнения." Хотя бы потому, что системе потребуются ресурсы, в том числе и временные, для поддержки этих 10 потоков.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311644
насчет не использовать - это будет долгий разовор. ну пусть - не использовать.

я не совсем удачно сказал. имелось в виду: не использовать при наличии штатных альтернатив с удовлетворительным результатом. т.е. при исчерпании всех других возможностей, в самую последнюю очередь
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311740
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AzartКакой выигрыш во времени при асинхронных запросах?
Поставим вопрос иначе: чем занят клиент в такой задаче?
1. Проверка состояния коннекта перед выдачей запроса.
2. Проверка состояния предыдущего рекордсета, полученного в этом коннекте.
3. Выдача запроса (команды):
Код: plaintext
Set rs = cmd.Execute(, , adCmdStoredProc + adAsyncFetch + adAsyncFetchNonBlocking + adAsyncExecute)
Если серверов много, этот алгоритм повторяется для каждого объекта из массива объектов.
В общем случае, это время сопоставимо с запуском потоков.
Далее:
4. обработчик события Connection.ExecuteComplete сообщает, как завершилась команда. Если выборка - пустая, рекордсет устанавливается в adState.Closed; иначе, исходя из .RecordCount устанавливается размер кэша.
5. Соединение (серверная часть) начинает передачу данных на клиент.
6. Обработчик события .FetchComplete возбуждается, когда весь рекордсет закачан.
Пп. 4-6 инициируются на клиенте сервером, асинхронно по отношению к клиенту.
Клиент только инициирует запросы; множественные серверы могут выполнять их независимо, в том числе - одновременно.
Так о каком проигрыше речь?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311790
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор2. Проверка состояния предыдущего рекордсета, полученного в этом коннекте. Это ещё зачем? После каждого получения данных коннекты и рекодсеты убиваются.
авторКлиент только инициирует запросы; множественные серверы могут выполнять их независимо, в том числе - одновременно.
Дело как раз в том что бы их одновременно инициировать!?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311833
Processor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Azart1.Это ещё зачем?
2. Дело как раз в том чтобы их одновременно инициировать!?1. Где гарантия, что DblClick система распознает как два Click?
2. Неужели здесь играет роль задержка при цикличном проходе через пп.1-3?
Ведь в комманде явно задан параметр adAsyncExecute !
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311857
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1.Причём тут Click или DbClick?
2. У меня вообще нету cmd.Execute, циклично я запускаю их так:
Код: plaintext
1.
2.
3.
4.
For i =  1  To KolCluster
                   Set TT(i) = New ADODB.Recordset
                   Set TT(i) = CN(LocalServerName(i), dbname, str)
'KolCluster - количество серверов с которых надо слить данные
Next i
Вы наверно предлашаете переписать функцию CN() ?
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311884
azart, ты што хотел с потоками делать?
вот это и делай.
у каждого асинхронного рекордсета должен быть СВОЙ
объект владелец, он же обработчик полученного результата.
...
Рейтинг: 0 / 0
Вызов функции с переменной в потоке.
    #33311935
Azart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если оставить все вводные моменты, то я хотел чтоб это выглядело так:
авторFor i = 1 To KolCluster
Set TT(i) = New ADODB.Recordset
ThreadControl(1).CreateNewThread(ByVal 0&, ByVal 0&, Set TT(i) = CN(LocalServerName(i), dbname, str), ByVal 0&, CreationFlags, lpThreadId)
'KolCluster - количество серверов с которых надо слить данные
Next i
... а тут уже делаю со всеми TT(i) что хочу :)

Не сбыться мечте идиота...
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Вызов функции с переменной в потоке.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]