Здравствуйте!
Не делал раньше многопотоковых приложений.
Сейчас понадобилось сделать 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