Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Потоки в VB / 23 сообщений из 23, страница 1 из 1
12.08.2010, 13:08
    #36788156
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Есть некая DLL (обычная, не ActiveX) от стороннего производителя. В ней реализованы CALLBACK- вызовы. Объявил в модуле CALLBACK-функцию, проверил ее работу - работает. Результаты, которые сторонняя DLL передает CALLBACK-функции, я сохраняю в коллекции. Коллекция объявлена в обычном классе. По таймеру (VB-шному, почему по нему, потому что нужно как можно быстрее добиться хоть какого-то решения) я читаю коллекцию, обрабатываю первый ее элемент и удаляю его. То есть имеем место очередь. С одной стороны CALLBACK функция пишет в коллекцию, с другой мой код ее читает. Разумеется возникли проблемы. Как наиболее простым способом сделать коллекцию потокобезопасной (средствами VB, альтернативными средствами)... есть у меня варианты через API, через mutex-ы, через SendMessage, но возможно есть более простой и надежный способ
...
Рейтинг: 0 / 0
12.08.2010, 13:11
    #36788168
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
разговор ни о чём. код свой сюда и ошибку, которая у вас возникает, и укажите в каком месте.
...
Рейтинг: 0 / 0
16.08.2010, 19:20
    #36794332
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Сейчас есть другая проблема. Обычная DLL-ка выполняет CALLBACK-вызовы. Для того, чтобы их обрабатывать, в обычном модуле описал подпрограмму с соответствующими параметрами. Все прекрасно работает. Теперь данное решение пытаюсь оформить в виде ActiveX DLL. Пока тестировал в группе проектов тоже все прекрасно работало. После того, как создал готовый ActiveX DLL (make dll) и подключил его в проект. Приложение стало валиться при обработке CALLBACK-а. В чем может быть проблема и как ее исправить?!

PS: Когда тестировал CALLBACK без ActiveX DLL, то выяснил, что поток выполнения главной программы и CALLBACK-а один и тот же (использовал API GetCurrentThreadID), то есть никакой синхронизации не требовалось. Когда создал ActiveX Dll и тестировал ее в группе проектов, то потоки были уже разными, но ничего не падало. Когда создал make dll и стал использовать ее, то потоки тоже разные, но приложение падает...

Очень срочно!
...
Рейтинг: 0 / 0
17.08.2010, 10:38
    #36794904
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
myauchaПриложение стало валиться при обработке CALLBACK-а.В скомпилированном виде, под отладчиком или в обоих случаях?

По-хорошему нужен исходник этой ActiveX dll.
...
Рейтинг: 0 / 0
17.08.2010, 14:20
    #36795565
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Пока оставим в стороне сей вопрос (пока так и не разобрался)... вернусь к нему немного позже... тут теперь другой вопрос... Почему в VB не работают API EnterCriticalSection и LeaveCriticalSection?! Приложение валится
...
Рейтинг: 0 / 0
17.08.2010, 14:23
    #36795572
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
myauchaПока оставим в стороне сей вопрос (пока так и не разобрался)... вернусь к нему немного позже... тут теперь другой вопрос... Почему в VB не работают API EnterCriticalSection и LeaveCriticalSection?! Приложение валится

может вы неправильно что-то делаете?
вот тут пример
...
Рейтинг: 0 / 0
17.08.2010, 14:45
    #36795638
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
...
Рейтинг: 0 / 0
17.08.2010, 14:45
    #36795640
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Ну вот, например, фрагмент для отладки. Что тут надо подправить?


' объявлено в модуле
Public Type CRITICAL_SECTION
dummy As Long
End Type

Public Declare Sub EnterCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
Public Declare Sub LeaveCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)

Public g_CS As CRITICAL_SECTION

' объявлено в форме
Private Sub Command1_Click()

EnterCriticalSection g_CS

Dim i As Long
i = 7

LeaveCriticalSection g_CS
End Sub
...
Рейтинг: 0 / 0
17.08.2010, 14:55
    #36795661
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Код: plaintext
InitializeCriticalSection gCS

сначала
...
Рейтинг: 0 / 0
17.08.2010, 15:01
    #36795676
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Initialize я делал... падало, как оказалось из-за отсутствия DeleteCriticalSection :))
...
Рейтинг: 0 / 0
17.08.2010, 15:02
    #36795680
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
myauchaInitialize я делал... падало, как оказалось из-за отсутствия DeleteCriticalSection :))

delete делать в Form_Unload надо
...
Рейтинг: 0 / 0
17.08.2010, 15:03
    #36795685
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
init соответственно в Form_Load
...
Рейтинг: 0 / 0
17.08.2010, 15:06
    #36795695
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
вот кусок класса (см ссылки выше)


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Private m_CS As CRITICAL_SECTION 'Critical section to avoid conflicts when signalling threads
Private m_pCS As Long 'Pointer to m_CS structure


Private Sub Class_Initialize()
Set m_RunningThreads = New Collection
m_EventHandle = CreateEvent( 0 ,  0 ,  0 , vbNullString)
m_pCS = VarPtr(m_CS)
InitializeCriticalSection m_pCS
End Sub
Private Sub Class_Terminate()
CleanCompletedThreads 'Just in case, this generally does nothing.
Debug.Assert m_RunningThreads.Count =  0  'Each worker should have a reference to this class
CloseHandle m_EventHandle
DeleteCriticalSection m_pCS
End Sub
...
Рейтинг: 0 / 0
17.08.2010, 17:48
    #36796225
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Не работает как надо. Какой-то полный бред получается.
Если я меняю объявления

Private m_objQueue As Collection
Private m_CS As CRITICAL_SECTION

местами, то VB падает при вызове любого метода. Если оставляю, как есть, то падает уже в потоке. Что не так, не пойму!


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
Option Explicit

Private Type CRITICAL_SECTION
    dummy As Long
End Type

Private Declare Sub InitializeCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
Private Declare Sub EnterCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
Private Declare Sub LeaveCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)
Private Declare Sub DeleteCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)

Private m_objQueue As Collection
Private m_CS As CRITICAL_SECTION

Public Enum QueueValueTypeEnum

    qvtResult
    qvtReplay
End Enum

' èíèöèàëèçàöèÿ
Private Sub Class_Initialize()

    Set m_objQueue = New Collection
    InitializeCriticalSection m_CS
End Sub

' äîáàâèòü â î÷åðåäü
Public Sub AddValue(ValueType As QueueValueTypeEnum, Value As Variant)

    EnterCriticalSection m_CS
    m_objQueue.Add Array(ValueType, Value)
    LeaveCriticalSection m_CS
End Sub

' ïîëó÷èòü ýëåìåíò èç î÷åðåäè
Public Function GetValue() As Variant

    EnterCriticalSection m_CS
    GetValue = m_objQueue( 1 )
    m_objQueue.Remove  1 
    LeaveCriticalSection m_CS
End Function

' êîëè÷åñòâî ýëåìåíòîâ
Public Function Count() As Long

    EnterCriticalSection m_CS
    Count = m_objQueue.Count
    LeaveCriticalSection m_CS
End Function

' îñâîáîæäåíèå
Private Sub Class_Terminate()

    DeleteCriticalSection m_CS
    Set m_objQueue = Nothing
End Sub
...
Рейтинг: 0 / 0
17.08.2010, 17:51
    #36796231
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Код: plaintext
1.
2.
3.
4.
5.
6.
Private m_pCS as Long

...
m_pCS = VarPtr(m_CS)
InitializeCriticalSection m_pCS
...
...
Рейтинг: 0 / 0
17.08.2010, 18:20
    #36796310
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
2 Konst_One

Если переписать

Private Declare Sub InitializeCriticalSection Lib "kernel32" (lpCriticalSection As CRITICAL_SECTION)

на

Private Declare Sub InitializeCriticalSection Lib "kernel32" (byval lpCriticalSection As long)

то будет ваш вариант. Сути это не меняет!
...
Рейтинг: 0 / 0
17.08.2010, 18:32
    #36796340
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
myauchaСейчас есть другая проблема. Обычная DLL-ка выполняет CALLBACK-вызовы. Для того, чтобы их обрабатывать, в обычном модуле описал подпрограмму с соответствующими параметрами. Все прекрасно работает. Теперь данное решение пытаюсь оформить в виде ActiveX DLL. Пока тестировал в группе проектов тоже все прекрасно работало. После того, как создал готовый ActiveX DLL (make dll) и подключил его в проект. Приложение стало валиться при обработке CALLBACK-а. В чем может быть проблема и как ее исправить?!

PS: Когда тестировал CALLBACK без ActiveX DLL, то выяснил, что поток выполнения главной программы и CALLBACK-а один и тот же (использовал API GetCurrentThreadID), то есть никакой синхронизации не требовалось. Когда создал ActiveX Dll и тестировал ее в группе проектов, то потоки были уже разными, но ничего не падало. Когда создал make dll и стал использовать ее, то потоки тоже разные, но приложение падает... 1) Почему нельзя сделать так, чтобы callback-функция устанавливалась и выполнялась в одном потоке? Это особенность используемой обычной DLL (непонятно по описанию, диаграммы нет)?

2) ActiveX DLL обязательно Threading Model должна быть Apartment Threaded, или может быть Single Threaded?
...
Рейтинг: 0 / 0
17.08.2010, 19:07
    #36796422
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
2 Бенедикт

Если забыть на время об ActiveX DLL (это моя неудачная попытка обернуть обычную DLL) и сосредоточить свое внимание на обычной DLL-ке, которая и предоставляет callback-вызовы, то она работает следующим образом... я в главной программе вызываю функцию send этой dll (вызов асинхронный). Через некоторое время DLL-ка вызывает callback-функцию, которую я объявил у себя в модуле. Если вызвать GetCurrentThreadID в главной программе и в callback-е, то ид. потоков разные. Поскольку в самом callback-е мне надо обращаться к глобальным данным, то я пытаюсь выполнить синхронизацию посредством критических секций... пока не очень получается... если есть идеи, как это сделать, то предложите. Надеюсь, понятно изложил
...
Рейтинг: 0 / 0
17.08.2010, 19:41
    #36796479
Бенедикт
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
myaucha,

да, так понятнее. К сожалению, плохой сценарий для VB6. Поток, порождаемый DLL, из которого вызывается callback-функция, не инициализирован для выполнения кода run-time библиотеки VB (версии 5, начиная с какого-то SP и 6 всех SP), а именно не настроен Thread Local Storage (TLS), подробнее см. статью "Create Worker Threads in DLLs" Мэтью Кёрланда (Matthew Curland) в VBPJ (Visual Basic Programmer's Journal) июня 1999 г. Попробуйте пока нарыть его статьи и книгу, там была глава по этому вопросу, он, по сути, единственный (ИМХО) авторитетный эксперт по теме. Если не найдёте, стукнитесь на мыло.
...
Рейтинг: 0 / 0
17.08.2010, 22:00
    #36796639
myaucha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Информацию не нашел... Как же мне все-таки корректно передать данные из CALLBACK-функции в поток основной программы? ;)
...
Рейтинг: 0 / 0
18.08.2010, 11:05
    #36797251
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Бенедиктmyaucha,

да, так понятнее. К сожалению, плохой сценарий для VB6. Поток, порождаемый DLL, из которого вызывается callback-функция, не инициализирован для выполнения кода run-time библиотеки VB (версии 5, начиная с какого-то SP и 6 всех SP), а именно не настроен Thread Local Storage (TLS), подробнее см. статью "Create Worker Threads in DLLs" Мэтью Кёрланда (Matthew Curland) в VBPJ (Visual Basic Programmer's Journal) июня 1999 г. Попробуйте пока нарыть его статьи и книгу, там была глава по этому вопросу, он, по сути, единственный (ИМХО) авторитетный эксперт по теме. Если не найдёте, стукнитесь на мыло.

см ссылку выше я давал на статью на основе его DLL
...
Рейтинг: 0 / 0
18.08.2010, 11:05
    #36797253
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
вот эта статья:
...
Рейтинг: 0 / 0
18.08.2010, 11:06
    #36797254
Konst_One
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Потоки в VB
Konst_Oneвот эта статья:

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


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