2012-04-21 3 views
0

저는 약 10 개의 창을 가진 Delphi7 프로젝트를 가지고 있습니다. MainWindow는 프로그램 시작시로드됩니다. 잠시 후 MainWindow는 프로젝트의 다른 창에 액세스하여 목록보기 항목을 추가하고 1-2 초 정도 업데이트합니다. 그러나이 창은 동결 된 것처럼 보이고 열어 본 후에 목록보기를 전혀 표시하지 않습니다.WindowFreeze VCL

SecondWindow.Show; 
SecondWindow.Close; 

그것은 문제없이 작동하지만, 전문가가 아닌 것 같다 : 내 MainWindow를 다음 명령의에서 onShow 절차가있는 경우

그것은 작동합니다. 나는 아이디어를 얻지 않고 어떻게 창을 그릴 수 있습니까?

편집 : CODE (나는 Indy9을 사용)

procedure TMainWindow.ServerSocketExecute(AThread: TIdPeerThread); 
begin 
/.... 
if Buffer = 'additem' then begin 
    Window2.ListView1.Items.Add; 
    Exit; 
    // ..... 
end; 
end; 

을합니다. 나는 Window2에서 모든 타이머를 제거했으며 여전히 정지 된 것 같습니다. 항목이 추가되거나 처음으로 두 번째 Windows를 열려고 할 때 주 윈도우가 순간적으로 멈 춥니 다.

+1

여기 조금만 더 가야합니다. 질문에 대한 중요한 개선이나 신성한 영감을 얻으려고합니다. 업데이트를 수행하는 코드를 표시 할 수 있습니까? 또한 1-2 초 업데이트는 어떻게 작동합니까? 타이머에 있니? –

+0

둘 다입니다. 제 2 차 양식에 타이머가 있습니다. 두 번째 양식에서 타이머를 제거하더라도 작동하지 않습니다. 문제가없는 목록보기 작업 등의 업데이트는 두 번째 양식이 먼저 표시되는 경우에만 수행됩니다./처음 항목을 추가 한 다음 SubItems.Strings [x] –

+0

을 업데이트하십시오. 메시지 대기열을 펌핑하는 것처럼 들리지만 작동하지 않습니다. 말하기가 불가능합니다. 여기에는 정보가 없습니다. 당신은 우리에게 더 많이 말해야합니다. 더 많은 코드를 보여주고 재현 해보자. –

답변

6

문제는 메인 GUI 스레드 외부에서, 즉 TMainWindow.ServerSocketExecute에서 VCL 메서드를 호출하고 있다는 것입니다. 이 이벤트는 작업자 스레드에서 실행됩니다. 작업자 스레드에서 VCL/GUI 코드를 호출하는 것은 단순히 게임 규칙에 위배됩니다. 모든 VCL 코드 은 기본 GUI 스레드에서을 실행해야합니다.

그래서 모든 VCL/GUI 코드가 GUI 스레드에서 실행되도록하여 문제를 해결하십시오. 이 작업을 수행하려면 TIdPeerThread.Synchronize() 메서드 또는 TIdSync 또는 TIdNotify 클래스를 사용하십시오.

내가 알지 못하는 세부 정보를 제공 한 덕분에 @ 감사합니다.

+4

좀 더 자세히 설명하자면, 'TIdTCPServer'는 멀티 스레드 구성 요소입니다. 'OnExecute' 이벤트는 메인 UI 스레드의 컨텍스트가 아니라 제공된 'TIdPeerThread' 객체에 의해 관리되는 작업자 스레드의 컨텍스트에서 시작됩니다. 'TListView'에 항목을 추가하는 것과 같은 VCL UI 작업은 기본 UI 스레드의 컨텍스트에서만 작동합니다. 'OnExecute' 이벤트에서 UI 연산을 수행하려면,'TIdPeerThread.Synchronize()'메소드 나'TIdSync' 또는'TIdNotify' 클래스를 사용하여 메인 스레드와 동기화해야합니다. –

+0

@remy이 유용한 설명에 감사드립니다. –