3

우선, 작업자 스레드가 컨트롤을 사용하지 않도록 설정하는 것이 좋은 디자인인지 확신 할 수 없습니다. 그러나 GUI와의 동기화없이 안전하게 할 수 있을까요?작업 스레드에서 TDataSet.DisableControls를 Synchronize()로 래핑하지 않고 실행할 수 있습니까?

TDataSet의의 코드는 다음과 같습니다

procedure TDataSet.DisableControls; 
begin 
    if FDisableCount = 0 then 
    begin 
    FDisableState := FState; 
    FEnableEvent := deDataSetChange; 
    end; 
    Inc(FDisableCount); 
end; 

그래서 그것을 할 안전한 보인다. EnableControls의 경우 상황이 달라질 수 있습니다. 하지만 DisableControls는 EnableControls 중에 발생하는 잠금 카운터 및 할당 이벤트 만 증가시키는 것으로 보입니다.

당신은 어떻게 생각하십니까?

+0

데이터 정렬로 컴파일하지 않으면'Inc'by 자체도 스레드 안전하지 않습니다. GUI 컨트롤에 어떻게 든 연결된 ** 모든 컨트롤 **을 사용하는 것에 대해 강력히 조언합니다. –

+1

또한 다음 시나리오를 고려하십시오. 스레드 입력, FDisableCount = 0, FDisableState = FState. 컨텍스트 전환이 발생하면 주 스레드가 FDisableCount를 감소시키고 FDisableState를 변경합니다 (이 경우 EnableControls에서 발생하는 것으로 보입니다). 컨텍스트 전환이 발생하고 스레드가 다시 실행 중이지만 이제는 잘못된 FDisableState로 작업합니다. –

+0

Lieven을 지적 해 주셔서 감사합니다. – Wodzu

답변

0

그렇게하는 것이 안전하지만 스레드에서이 메서드를 호출하는 순간에 실행되는 코드에서 이러한 플래그가 사용되므로 잘못 될 수 있습니다.

컨트롤이 사용하지 않는 경우에만이 데이터 집합을 사용하여 스레드를 시작하기 때문에 DisableControls에 대한 호출을 동기화합니다. EnableControls 호출을 동기화하거나 PostMessage를 사용하여 양식에 메시지를 게시 할 수 있습니다. 그런 식으로 스레드는 주 스레드를 기다릴 필요가 없습니다.

그러나 내 직감은 GUI와 스레드에 대해 동일한 데이터 세트를 사용하지 않는 것이 더 나을 것이라고 말합니다.

0

실제 코드를 조회하지 않고 : 주 스레드가 현재 FDisableCount, FDisableState 및 FEnableEvent에 액세스하지 못하는 것이 확실 할 수있는 한 안전 할 수 있습니다. 경쟁 조건이 발생할 가능성이 있습니다.

메인 스레드 내에서 DisableControls를 호출하는 것이 좋습니다.