2010-08-06 5 views
6

가끔 BeginInvoke가 호출 될 때 위임 메서드를 실행하는 데 1 초 이상 걸립니다.Delegate.BeginInvoke 지연

지연 이유는 무엇입니까? 나는이 문제를 하루에 1-2 회 연속적으로 실행되는 응용 프로그램에서 얻습니다.

도와주세요.

감사합니다.

+2

이'Control.BeginInvoke' 또는'Delegate.BeginInvoke'입니까? –

+2

새로운 스레드를 만들고 있습니다. 그러나 이것이 얼마나 오래 걸릴지는 알 수 없습니다. 아마도 매우 빠릅니다. –

+0

새 스레드를 만드는 것은 상대적으로 비용이 많이 듭니다. –

답변

7

스레드 풀 관리자는 CPU 코어가있는만큼 많은 스레드가 실행되도록 허용합니다. 하나가 완료 되 자마자 대기열에서 대기중인 다른 하나가 실행될 수 있습니다.

두 번째로 1 초에 두 번 실행중인 스레드에서 진행되고있는 작업을 다시 평가합니다. 완료하지 못하면 차단 된 것으로 간주하여 대기중인 다른 스레드를 실행할 수 있습니다. 일반적인 2- 코어 CPU에서는 두 개의 스레드가 즉시 실행되고 세 번째 스레드는 1 초 후에 시작되고 네 번째 스레드는 1.5 초 후에 시작됩니다.

음, 두 번째가 있습니다. Q & D 수정은 ThreadPool.SetMinThreads()를 사용하는 것이지만 슬레 그 해머 솔루션입니다. 실제 문제는 프로그램이 장기 실행 작업을 위해 스레드 풀 스레드를 사용하고 있다는 것입니다. 많은 코드를 실행하거나 어떤 종류의 I/O 요청을 차단하기 때문입니다. 후자가 더 일반적인 경우입니다.

해결 방법은 이 아니며은 이러한 차단 스레드에 대해 스레드 풀 스레드를 사용하지만 대신 Thread 클래스를 사용합니다. 스레드가 실제로 CPU주기를 굽히는 경우이 작업을 수행하지 마십시오. 모든 작업이 느려집니다. 쉽게 알 수 있습니다. Taskmgr에 100 % CPU로드가 표시됩니다.exe

+0

안녕 Hans, 답장을 보내 주셔서 감사합니다. 어떤 스레드 풀 스레드가 IO에서 차단 중이거나 더 많은 CPU주기를 사용하는지 쉽게 이해할 수 있습니까? 감사합니다. – Maanu

+0

당신이 모르는 경우에는 너무 많이 사용합니다. start + end를 로그하여 알 수 있습니다. –

2

BeginInvoke의 우선 순위를 설정할 수 있습니까?

http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx

는 BeginInvoke는 통화 대기 다른 당신이 있습니까?

"동일한 BeginInvoke 호출이 동일한 DispatcherPriority에서 만들어진 경우 호출이 이루어진 순서대로 실행됩니다."

http://msdn.microsoft.com/en-us/library/ms591206.aspx

+0

Delegate.BeginInvoke입니다. 로깅으로 차이를 측정합니다. BeginInvoke를 호출하기 전에 로그 항목이 있습니다. 로그 엔트리가 Delegate 메소드에도 있습니다. – Maanu

4

당신이있어 당신이 ThreadPool을 사용하여 간접적으로 Delegate.BeginInvoke를 사용하고 있기 때문에. ThreadPool은 완료된 스레드를 재활용하고 새 스레드를 구성하고 완료된 스레드를 찢어 버리지 않고 재사용 할 수있게합니다.

그래서 ... Delegate.BeginInvoke을 사용하면 ThreadPool에 실행될 작업에 사용 가능한 스레드가 있다고 판단되는 즉시 대기열에 호출 할 메소드가 추가됩니다. 그러나 ThreadPool에 사용 가능한 스레드가 없으면 기다리게됩니다.

System.Threading.ThreadPool에는 사용할 수있는 최대 스레드 수, 최대 값 등을 표시하는 몇 가지 속성과 메서드가 있습니다.이 카운트를 모니터링하여 ThreadPool이 얇게 보일지 확인합니다.

그런 경우 인 경우 가장 좋은 해결책은 ThreadPool이 수명이 짧은 (작은) 작업에만 사용되도록하는 것입니다. 장기 실행 작업에 사용되는 경우 해당 작업은 ThreadPool을 점유하는 대신 자체 전용 스레드를 사용하도록 수정해야합니다.

+0

안녕 STW, 어떻게 ThreadPool 매개 변수를 모니터링합니까? 설문 조사 또는 다른 거? 감사합니다. – Maanu

+0

'System.Threading.Timer'와 같은 간단한 타이머를 사용하여 스레드 풀 상태를 수집하고보고 할 수있는 메서드를 호출 할 수 있습니다. – STW

+0

...이 사실을 알지 못했지만 거기에있는 것처럼 보입니다. http://msdn.microsoft.com/en-us/library/ff650682.aspx – STW