Здравствуйте!
Не делал раньше многопотоковых приложений.
Сейчас понадобилось сделать listIconGadget, заполняемый в асинхронном режиме. Зачем? Да потому что строк более 13000 на данный момент и будет больше.
Хотелось бы, что бы программа не зависала при заполнении листикона. Ниже код (упрощенный и урезанный).
Как бы всё работает, так как я хочу. Но если в поле поиска несколько раз туда-сюда повбивать символы, то программа рано или поздно выходит в ошибку. Сейчас на 97 строке, где находится Event=WaitWindowEvent() ; Но это сейчас так, а в основной программе другая строка и функция.
Подскажите, пожалуйста, как делать безопасные пногопоточные приложения. И что исправить конкретно в моём примере. Галочка "безопасный трид" стоит.
Enumeration
#win_inddb
#filtr_of_list_of_eep_membd
#panel_gadget_win_indbd_1
#list_of_eep_membd_1
#version_membd_1
#total_in_membd_1
#here_shown_1
EndEnumeration
Structure eep_to_db; Структура для листа загружаемой внутренней БД
nn_def.l
code.s
code2.s
model.s
addr.l
size.l
type.s
EndStructure
NewList load_list_inddb.eep_to_db ()
For i=1 To 10000
AddElement (load_list_inddb.eep_to_db ())
load_list_inddb.eep_to_db ()\nn_def=i
load_list_inddb.eep_to_db ()\code=RSet(Str(Random(99999999999)), 11, "0")
load_list_inddb.eep_to_db ()\code2=RSet(Str (Random(999999999999)), 12, "0")
load_list_inddb.eep_to_db ()\model=RSet(Str (Random(999999999)), 9, "0")
load_list_inddb.eep_to_db ()\size=Random(32768)
load_list_inddb.eep_to_db ()\type=Str (Random(4))
Next
db_version_1$="01-02-2022"
Procedure fill_gadget_last_list (gadget_to)
MeasureIntervalStart()
timest = ElapsedMilliseconds()
Shared str_to_seearch$, filtr_a.b, here_shown, load_list_inddb ()
If str_to_seearch$="Search..."
str_to_seearch$=""
EndIf
ResetList (load_list_inddb ())
ClearGadgetItems(gadget_to)
i_lli=1; счётчик показанных прошивок
HideGadget(gadget_to, 0); изменить параметр на 1 что бы скрыть лист при заполнении (увеличивает скорость заполнения, но не интересно)
ForEach load_list_inddb()
If filtr_a=0 Or (filtr_a.b=%00000001 And load_list_inddb()\type="ARCADIA") Or (filtr_a.b=%00000010 And load_list_inddb()\type="EVO II")
If str_to_seearch$="" Or FindString(load_list_inddb()\code, str_to_seearch$, 1) Or FindString(load_list_inddb()\code2, str_to_seearch$, 1) Or FindString(ReplaceString(load_list_inddb()\model, " ", ""), UCase(str_to_seearch$), 1)
code_all$=load_list_inddb()\code
If load_list_inddb()\code2
code_all$=code_all$+"/"+load_list_inddb()\code2
EndIf
AddGadgetItem(gadget_to, i_lli-1, Str(load_list_inddb()\nn_def)+Chr(10)+load_list_inddb()\model+Chr(10)+code_all$+Chr(10)+Str(load_list_inddb()\size)+Chr(10)+load_list_inddb()\type)
SetGadgetItemData(gadget_to, i_lli-1, load_list_inddb()\addr)
i_lli+1
If IsGadget(here_shown) And i_lli%57=0
SetGadgetText(here_shown, "Shown: "+Str(i_lli-1))
EndIf
EndIf
EndIf
Next
HideGadget(gadget_to, 0)
If IsGadget(here_shown)
SetGadgetText(here_shown, "Shown: "+Str(i_lli-1))
EndIf
Debug (ElapsedMilliseconds()-timest)
EndProcedure
hWnd_inddb=OpenWindow(#win_inddb,0,0,580,480,"IND Data Base Parser © 2016 KDS Soft", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
;Gadgets
y0=32
StringGadget(#filtr_of_list_of_eep_membd, 5, 4, 130, 18, "")
SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)
PanelGadget(#panel_gadget_win_indbd_1,1, y0, WindowWidth(#win_inddb)-4, WindowHeight(#win_inddb)-y0)
AddGadgetItem (#panel_gadget_win_indbd_1, -1, "Main DB 1")
ListIconGadget(#list_of_eep_membd_1, 3, 5+22, GadgetWidth(#panel_gadget_win_indbd_1)-12, GadgetHeight(#panel_gadget_win_indbd_1)-24-y0, "N", 50, #PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection);|#PB_ListIcon_HeaderDragDrop)
AddGadgetColumn(#list_of_eep_membd_1, 2, "Model", 135)
AddGadgetColumn(#list_of_eep_membd_1, 3, "Code", 210)
AddGadgetColumn(#list_of_eep_membd_1, 4, "Size", 55)
AddGadgetColumn(#list_of_eep_membd_1, 5, "Type", 80)
; SetGadgetFont(#list_of_eep_membd, FontID(0))
GadgetToolTip(#list_of_eep_membd_1, "Double click to select and open in the Sky Prog")
StringGadget(#version_membd_1, 5, 3, 150, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
StringGadget(#total_in_membd_1, 5+162, 3, 130, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
StringGadget(#here_shown_1, 5+162+142, 3, 100, 18, "" , #PB_String_ReadOnly|#PB_String_BorderLess)
; Изменим цвет стрингаджетов на белый вместо серого
SetGadgetColor (#version_membd_1, #PB_Gadget_BackColor, $FFFFFF)
SetGadgetColor (#total_in_membd_1, #PB_Gadget_BackColor, $FFFFFF)
SetGadgetColor (#here_shown_1, #PB_Gadget_BackColor, $FFFFFF)
win_repeats=0; счётчик циклов окна
thread_tab_1=0;hnd для thread
Repeat ;
Event=WaitWindowEvent() ;
If Event=#WM_KEYDOWN ; Была нажата кнопка
; If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
If GetActiveGadget()<>#filtr_of_list_of_eep_membd
; SetGadgetText (#filtr_of_list_of_eep_membd, LCase(Chr(EventwParam())))
SetActiveGadget(#filtr_of_list_of_eep_membd)
; SendMessage_(GadgetID(#filtr_of_list_of_eep_membd),#EM_SETSEL,100000000,100000000)
SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
; search_change=1
EndIf
EndIf
If Event = #PB_Event_Gadget; Событие гаджетов
If EventGadget()=#filtr_of_list_of_eep_membd
If EventType()=#PB_EventType_Change
search_change=1
EndIf
If EventType()=#PB_EventType_LostFocus
If GetGadgetText(#filtr_of_list_of_eep_membd)=""
SetGadgetText(#filtr_of_list_of_eep_membd, "Search...")
SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $999999)
EndIf
EndIf
If EventType()=#PB_EventType_Focus
If GetGadgetText(#filtr_of_list_of_eep_membd)="Search..."
SetGadgetColor(#filtr_of_list_of_eep_membd, #PB_Gadget_FrontColor, $000000)
SetGadgetText(#filtr_of_list_of_eep_membd, "")
EndIf
EndIf
EndIf
EndIf
If win_repeats=0 Or search_change
search_change=0
If thread_tab_1 And IsThread(thread_tab_1)
KillThread (thread_tab_1)
EndIf
str_to_seearch$=GetGadgetText(#filtr_of_list_of_eep_membd)
filtr_a.b=0
here_shown=#here_shown_1
thread_tab_1=CreateThread (@fill_gadget_last_list (), #list_of_eep_membd_1);, load_list_inddb_1())
SetGadgetText(#version_membd_1, "Database version: "+db_version_1$) ; Показываем версию БД
EndIf
win_repeats+1
Until Event=#PB_Event_CloseWindow