2011-11-29 4 views
2

별도의 스레드가 TMediaPlayer 개체의 Position 속성을 쿼리 할 수없는 이유는 무엇입니까?별도의 스레드에서 TMediaPlayer.Position에 액세스

필자는 TMediaPlayer 구성 요소가있는 폼 인 Delphi DLL을 작성했습니다. 응용 프로그램은 정기적으로 DLL로 호출하고,이 DLL 호출은 DLL의 형태에 TMediaPlayer 객체의 위치 및 길이 값을 조회 할 수 있습니다 응용 프로그램의 컨텍스트에서 호출 할 때 위의 기능이 잘 작동

procedure TDLLForm.SongPosUpdate(); 
var 
    new_pos: integer; 
    new_len: integer; 
begin 
    new_pos := AudioPlayer.Position; 
    new_len := AudioPlayer.Length; 
end; 

DLL을로드했습니다. TMediaPlayer 개체의

// TTimerThread: Constructor 
constructor TTimerThread.Create(F: TDLLForm); 
begin 
    DllForm := F; 
    inherited Create(True); 
    inherited priority := tpHighest; 
end; 


// TTimerThread: Execute 
procedure TTimerThread.Execute; 
begin 
    while not Terminated do 
    begin 
    DLLForm.SongPosUpdate(); 
    Sleep (1000); 
    end; 
end; 

다른 속성 : 그러나, DLL이 별도의 스레드를 (TThread의 서브 클래스) 생성하고 새 스레드가 같은 함수를 호출하면, 객체의 위치 및 길이 속성에 대한 잘못된 값을 얻는다 (예 : AudioPlayer.FileName)은 스레드에서 성공적으로 쿼리 할 수 ​​있지만 Position/Length는 쿼리 할 수 ​​없습니다. 재생을 시작한 원래 스레드의 컨텍스트에서 호출되지 않을 때 TMediaPlayer가 정확한 위치/길이를 나타내지 않는 이유는 무엇입니까?

답변

4

UI 컨트롤은 주 VCL 스레드 외부에서 직접 액세스하는 것이 안전하지 않습니다. 작업자 스레드에서 질의를 받으면 ANY 속성이 올바르게 작동한다는 뚜렷한 보장이 없습니다. 이 경우 FileName 속성은 TMediaPlayer 클래스의 멤버 인 String 변수를 읽음으로써 일반적으로 충분히 안전하지만 PositionLength 속성은 미디어 장치에 MCI 명령을 보내야합니다. 발생할 수 있습니다.

+0

감사합니다. 적절한 방법이 있습니까? 별도의 스레드가있는 이유는 DLL의 호출 응용 프로그램 스레드가 일부 작업에서 일시적으로 차단 된 경우에도 DLL 활동을 계속 유지하기 위해서입니다. 이전에 TTimer를 사용하여 작업을 수행했지만이 작업은 일반적인 VCL 스레드를 통과하는 낮은 우선 순위 이벤트이므로 응용 프로그램이 사용 중일 때 백업 할 수 있음을 알고 있습니다. – ukembedded

+0

스레드가'TMediaPlayer' 속성을 직접 쿼리하는 대신,'TMediaPlayer' 속성을 쿼리하고 그 값을 스레드로부터 안전한 변수에 저장하는'TTimer'를 실행하는'TMediaPlayer'의 부모'TForm'을 가질 수 있습니다. 스레드는 다음에서 읽을 수 있습니다. 대안은'TThread.Synchronize()'를 사용하는 것이지만, DLL 내부에 문제가 있습니다. 주 스레드가 백업되면 (MCI가 재생을 위해 자체 배경 스레드를 사용하지 않는 한) 미디어 재생이 어쨌든 백업 될 수 있습니다 (주 스레드에서 너무 많은 작업을하고 있음을 의미). –

+0

감사합니다. 작업자 스레드에서 액세스 할 수있는 컨트롤을 결정하는 데 사용할 수있는 규칙이 있는지 알고 있습니까? 예를 들어 TPaintBox의 비트 맵을 작업자 스레드에서 업데이트 할 수 있습니다. 스레드 컨트롤과 컨트롤 중 어떤 컨트롤이 틀림 없는지 어떻게 알 수 있습니까? - 12 분 전에 – ukembedded

관련 문제