사례 배경:
전체 기능은 실제로 데이터베이스에서 데이터를 검색한 다음 인터페이스에서 재생하는 것입니다. 간단히 말해서 검색하는 것이 문자열 데이터라는 점을 제외하면 온라인으로 비디오를 보고 음악을 듣는 것과 유사합니다. 그들이 검색하는 것은 스트림 데이터입니다. 전체 데이터를 10개 부분으로 나누면 10개의 스레드가 동시에 데이터베이스에서 데이터를 가져와 10개의 대기열에 넣습니다. 재생 진행 상황을 드래그하여 일시 중지하고 재생을 재개하고 재생 속도를 제어하세요. 글쎄요, 이 기능은 간단해 보이고 실행하기 어렵지 않습니다. 그러나 나중에 몇 가지 문제가 발견되고, 이러한 문제를 파헤쳐 보면 기억할 가치가 있다고 생각되는 몇 가지 사항이 발견되었습니다.
핵심 사항:
1. Silverlight 백그라운드 스레드 BackgroundWorker m_GetReplayData= new BackgroundWorker()
2. 인터페이스 컨트롤에 대한 크로스 스레드 액세스, this.Dispatcher.BeginInvoke(/Access 인터페이스 UI); 3. JavaScript 스타일 함수 포인터: var ShowSIngleLog = function(){} ; (상위 페이지에서)
4. 하위 페이지는 상위 페이지의 이벤트를 등록합니다: var fatharWindow = window.opener; fatharWindow .ShowSIngleLog =function (){//재생 데이터 showTrace()};
5.javascript 엔진 스레드, 인터페이스 렌더링 스레드, 브라우저 이벤트 트리거 스레드
6. , 모든 것이 동기화되었습니다. 예, 두 개의 스레드가 동시에 실행되지 않습니다.
문제:
Silverlight는 인터페이스 데이터 재생 효과를 얻기 위해 Silverlight 스레드의 루프를 통해 JS 메서드를 호출합니다. 왜냐하면 Silverlight는 호출만 할 수 있기 때문입니다. 이 페이지의 JS 방식이지만 트랙 재생 페이지는 메인 페이지에서 팝업되는 서브 페이지이므로 메인 페이지의 빈 함수 포인터를 사용하고 서브 페이지는 목적을 달성하기 위해 상위 페이지의 이벤트를 등록합니다. Silverlight에서 하위 페이지 메서드를 호출합니다(위에서 언급한 3번 항목). 신중하게 고민하고 논의한 끝에 문제가 없다고 판단했고, 마친 후에도 문제가 없었습니다. 로컬 테스트는 모두 수백, 수천 개의 데이터를 사용했으며, 진행을 중지하고 일시정지하고 드래그하는 데에는 큰 문제가 없었습니다. 유일한 문제는 상위 페이지 인터페이스가 약간 멈췄다는 것입니다. 처음에는 이 문제에 주의를 기울이십시오. 테스트를 해보니 20,000개가 넘는 데이터가 5분 동안 재생된 후 트랙 재생 페이지의 중지, 드래그 진행, 일시 중지 및 재생 버튼이 모두 작동하지 않았습니다. 현상이 참 이상하더군요. 한때는 테스트 머신의 문제인 줄 알았는데, 알고보니 대용량 데이터의 문제였습니다. This.Dispatcher.BeginInvoke(/access 인터페이스 UI)는 매우 간단하고 평범한 호출처럼 보이지만 두 가지 특징을 가지고 있습니다.
1 비동기식입니다. 즉, 조정하면 즉시 실행되지 않을 수 있습니다. 먼저 조정하면 즉시 실행되지 않을 수 있습니다.
2. 이 메서드는 브라우저 인터페이스 렌더링 스레드를 점유해야 하며 이 스레드와 자바스크립트 엔진 스레드는 상호 배타적입니다.
20,000개가 넘는 데이터로 처음에는 재생속도를 조절해서 처음에는 문제가 없었지만 나중에는 이 방법으로 데이터가 많이 막혀서 브라우저 인터페이스 렌더링 스레드가 지속적으로 점유되는 현상이 발생했고, 메인 페이지가 멈출 때까지 매우 정체되게 만듭니다. 메인 페이지를 클릭하면 브라우저 이벤트 트리거 스레드가 실행되어야 하는데 이때 인터페이스 렌더링 스레드가 실행 중이어서 매우 멈춥니다.
해결책:
this.Dispatcher.BeginInvoke(/Access 인터페이스 UI), 이는 분명히 이것 때문에 발생한 것이므로 대안을 찾으십시오. 데이터 큐가 실버라이트에 배치되어 있는 것으로 알고 있는데, 자바스크립트 큐로 변경했습니다. 데이터 재생은 실버 스레드에 의존하지 않으며, 정기적으로 데이터를 재생하기 위해 settimeout(이 방법은 IE6에서 메모리 누수가 발생하므로 처음에는 거부했습니다)을 사용합니다. 결과는 아름답고, 페이지가 매우 매끄럽고, 비동기 문제가 없으며, 동기적으로 재생될 데이터를 제어할 필요가 없으며 비교적 간단합니다.
이유 분석:
Silerlight로 플레이할 때는 멈춤 현상이 심하고 Setimeout으로 플레이할 때는 멈춤 현상이 심한 이유는 무엇입니까? 둘 다 계속해서 플레이하고, Setimeout이 플레이 중일 때 페이지를 클릭하면 페이지에서도 이벤트에 응답할 수 있습니다. . 이 문제를 해결하려면 이벤트에서 자바스크립트 엔진을 구동해야 합니다. 페이지가 멈추는 이유는 위에서 언급한 바와 같습니다. 주로 settimeout 재생이 멈추지 않는 이유를 설명하고 싶습니다. 브라우저의 JavaScript 엔진은 이벤트 기반입니다. 여기서 이벤트는 브라우저에 의해 할당된 다양한 작업으로 간주될 수 있습니다. 이러한 작업은 작업을 추가하기 위해 setTimeout을 호출하는 것과 같이 JavaScript 엔진에 의해 현재 실행되는 코드 블록에서 발생할 수 있습니다. 또는 인터페이스 요소 마우스 클릭 이벤트, 예약된 트리거 시간 도착 알림, 비동기 요청 상태 변경 알림 등과 같은 브라우저 커널의 다른 스레드에서 올 수 있습니다. 코드 관점에서 작업 엔터티는 다양한 콜백 함수이며 JavaScript는 엔진은 항상 작업 대기열을 기다리고 있습니다. 단일 스레드 관계로 인해 이러한 작업은 엔진에 의해 차례로 대기열에 추가되고 처리되어야 합니다. 따라서 데이터를 재생할 때 작업 인터페이스가 작업 대기열에 추가되고 실행되면 당연히 사용자는 전체 페이지가 더 이상 중단되지 않는다고 느낄 것입니다.