2009-04-23 2 views
3

사용자 행동에 반응하는 내 앱을 유지하는 데 문제가 있습니다. 따라서 여러 스레드간에 메시지 처리를 분할하고 싶습니다.메시지 처리가 너무 느리므로 비정상적이고 반응이없는 UI가 발생합니다.이를 완화하기 위해 여러 스레드를 어떻게 사용할 수 있습니까?

간단히 여러 개의 스레드를 만들고, 모두 동일한 메시지 큐에서 읽고 각 메시지를 처리 ​​할 수있게 할 수 있습니까?

그렇다면 어떻게 수행 할 수 있습니까?

그렇지 않은 경우이 문제를 해결할 다른 방법을 제안 할 수 있습니까?

답변

13

메시지 펌프 또는 UI 요소와 상호 작용하는 스레드를 두 개 이상 가질 수 없습니다. 그 방법은 광기를 속인다.

작업자 스레드로 배포 할 수있는 긴 처리 작업이있는 경우 그렇게 할 수 있지만이를 관리하려면 다른 스레드 안전 큐를 사용해야합니다.

+0

하지만 ... 왜? 나는 이미 대기열을 가지고 있습니다. 분명히 또 다른 * 하나를 만드는 것보다 단지 그것을 재사용 할 수있는, 끔찍하고, 문서화되고, 끔찍하게도 복잡한 수단이 있습니다. – Shog9

+0

해킹 방법이있다해도 문제를 처리하는 적절한 방법이 아닙니다. Mark가 설명합니다. 창 크기 조정과 같은 문제가있는 경우 WM_SIZE를 처리해야하는 코드가있는 것 같습니다. –

+1

"그런 식으로 광기가있다"는 것은 도움이되지 않습니다. Windows UI 코드는 스레드로부터 안전하지 않습니다. 다른 이유는 없습니다. – Bill

0

긴 작업을 처리 할 때 별도의 스레드를 만드십시오. 즉, 간단하게 유지하십시오. 실행중인 코드가 너무 길어서 별도의 스레드가 있어야하는 코드입니다.

4

나중에 나중에 비동기식 에이전트 API (내가 작업하고있는 플러그인)를 the yet to be released Visual Studio 2010에서 사용한다고 말하고 싶지만 요즘 말하는 도구는 작업 내용을 메시지에서 분리하는 것입니다. 전달하는 펌프는 가능한 한 작은 작업으로 메시지를 식별하고 작업을 처리 할 다른 스레드로 전달합니다 (필요한 스레드 로컬 정보가 없기를 바랍니다). 그것을 다른 스레드에 전달하는 것은 잠금 또는 잠금이없는 일종의 스레드 안전 큐에 삽입 한 다음 다른 스레드가 대기열에서 항목을 가져 오거나 (또는 ​​직접 끌어 올 수있는) 이벤트를 설정할 수 있음을 의미합니다. 효율성을 위해 스레드 풀과 함께 '작업 도용 큐'를 사용할 수 있습니다.

이것은 UI 스레드를 작동시켜 UI 스레드가 추가 작업을 수행하도록합니다 (예 : 작업 결과 그리기). UI 스레드를 깨우고 결과를 확인하기 위해 Windows 메시지를 생성해야합니다. , UI 스레드에서 실행할 다른 작업 준비 대기열을 갖는 것이 쉬운 방법입니다. 다음과 같은 대기열을 상상해보십시오 : 기본적으로 UI 스레드에서 비어 있지 않은지 여부를 확인할 수 있습니다. 작업 항목이 있으면 인라인으로 실행할 수 있습니다. 작업 객체는 가능한 한 짧게 살아야하며 바람직하게는 을 차단하지 말아야합니다.은 전혀 차단되지 않습니다.

여전히 움직임이 빠른 반응을 보이는 경우 도움이 될 수있는 또 다른 기술은 스레드 콜백이 16ms 이상 실행되지 않고 잠금을 수행하지 않고 모든 종류의 I/O UI 스레드에서. 이러한 작업을 식별하는 데 도움이되는 일련의 도구가 있으며 가장 자유롭게 사용할 수있는 것은 'windows performance toolkit'입니다.