Delegate.BeginInvoke Delay
Asked Answered
R

3

8

Sometimes when Delegate.BeginInvoke is invoked, it takes more than one second to execute the delegate method.

What could be the reasons for the delay? I get this issue 1 or 2 times a day in an application which runs continuosly.

Please help me.

Thanks!

Renn answered 6/8, 2010 at 13:26 Comment(5)
Is this Control.BeginInvoke or Delegate.BeginInvoke?Mancilla
It is making a new thread - but I don't know how long this should take. Probably very fast.Mosira
Creating a new thread is relatively expensive.Ruinous
How are you measuring this delay? Have you tried doing something like Console.WriteLine(DateTime.Now); right before calling .BeginInvoke() as well as immediately within the delegate method?Intort
It is Delegate.BeginInvoke. I measure the difference by logging. There is a log entry before calling BeginInvoke. A log entry is there in the Delegate method also..Renn
H
9

The thread pool manager makes sure that only as many threads are allowed to execute as you have CPU cores. As soon as one completes, another one that's waiting in the queue is allowed to execute.

Twice a second, it re-evaluates what's going on with the running threads. If they don't complete, it assumes they are blocked and allows another waiting thread to run. On the typical two-core CPU, you'll get two threads running right away, the 3rd thread starts after one second, the 4th thread after 1.5 second, etcetera.

Well, there's your second. The Q&D fix is to use ThreadPool.SetMinThreads(), but that's the sledgehammer solution. The real issue is that your program is using thread pool threads for long-running tasks. Either because they execute a lot of code or because they block on some kind of I/O request. The latter being the more common case.

The way to solve it is to not use a thread pool thread for such a blocking thread but use the Thread class instead. Don't do this if the threads are actually burning CPU cycles, you'll slow everything down. Easy to tell, you'll see 100% cpu load in Taskmgr.exe

Hogan answered 6/8, 2010 at 15:29 Comment(2)
Hi Hans, Thanks for the reply. Is there any easy way to understand which thread pool thread is blocking on IO or taking more CPU cycles. Thanks!Renn
If you don't know then you use too many of them. You can find out by logging start+end.Hogan
I
5

Since you're using Delegate.BeginInvoke then you're, indirectly, using the ThreadPool. The ThreadPool recycles completed threads and allows them to be reused without going through the expense of constructing new threads and tearing completed threads down.

So... when you use Delegate.BeginInvoke you're adding the method to be invoked to a queue, as soon as the ThreadPool thinks it has an available thread for your task it will execute. However, if the ThreadPool is out of available threads then you'll be left waiting.

System.Threading.ThreadPool has several properties and methods to show how many threads are available, maximums, etc. I would try monitoring those counts to see if it looks like the ThreadPool is being spread thin.

If that's the case then the best resolution is to ensure that the ThreadPool is only being used for short-lived (small) tasks. If it's being used for long-running tasks then those tasks should be modified to use their own dedicated thread rather than occupying the ThreadPool.

Intort answered 6/8, 2010 at 13:51 Comment(3)
Hi STW, How do you monitor ThreadPool parameters? Poll or Something else? Thanks!Renn
You could use a simple timer, such as System.Threading.Timer to invoke a method which could collect and report on the threadpool statusIntort
...I wasn't aware of this, but it also looks like there may be performance counters available specifically to do this: msdn.microsoft.com/en-us/library/ff650682.aspxIntort
K
2

Can you set the priority of the BeginInvoke?

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

Do you have other BeginInvoke calls waiting?

"If multiple BeginInvoke calls are made at the same DispatcherPriority, they will be executed in the order the calls were made."

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

Kelula answered 6/8, 2010 at 13:38 Comment(1)
It is Delegate.BeginInvoke. I measure the difference by logging. There is a log entry before calling BeginInvoke. A log entry is there in the Delegate method also..Renn

© 2022 - 2024 — McMap. All rights reserved.