별도의 스레드가 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가 정확한 위치/길이를 나타내지 않는 이유는 무엇입니까?
감사합니다. 적절한 방법이 있습니까? 별도의 스레드가있는 이유는 DLL의 호출 응용 프로그램 스레드가 일부 작업에서 일시적으로 차단 된 경우에도 DLL 활동을 계속 유지하기 위해서입니다. 이전에 TTimer를 사용하여 작업을 수행했지만이 작업은 일반적인 VCL 스레드를 통과하는 낮은 우선 순위 이벤트이므로 응용 프로그램이 사용 중일 때 백업 할 수 있음을 알고 있습니다. – ukembedded
스레드가'TMediaPlayer' 속성을 직접 쿼리하는 대신,'TMediaPlayer' 속성을 쿼리하고 그 값을 스레드로부터 안전한 변수에 저장하는'TTimer'를 실행하는'TMediaPlayer'의 부모'TForm'을 가질 수 있습니다. 스레드는 다음에서 읽을 수 있습니다. 대안은'TThread.Synchronize()'를 사용하는 것이지만, DLL 내부에 문제가 있습니다. 주 스레드가 백업되면 (MCI가 재생을 위해 자체 배경 스레드를 사용하지 않는 한) 미디어 재생이 어쨌든 백업 될 수 있습니다 (주 스레드에서 너무 많은 작업을하고 있음을 의미). –
감사합니다. 작업자 스레드에서 액세스 할 수있는 컨트롤을 결정하는 데 사용할 수있는 규칙이 있는지 알고 있습니까? 예를 들어 TPaintBox의 비트 맵을 작업자 스레드에서 업데이트 할 수 있습니다. 스레드 컨트롤과 컨트롤 중 어떤 컨트롤이 틀림 없는지 어떻게 알 수 있습니까? - 12 분 전에 – ukembedded