views:

76

answers:

2

Hi,

I'm running a winservice that has 2 main objectives.

  1. Execute/Handle exposed webmethods.
  2. Run Inner processes that consume allot of CPU.

The problem is that when I execute many inner processes |(as tasks) that are queued to the threadpool or taskpool, the execution of the webmethods takes much more time as WCF also queues its executions to the same threadpool. This even happens when setting the inner processes task priority to lowest and setting the webmethods thread priority to heights.

I hoped that Framework 4.0 would improve this, and they have, but still it takes quite allot of time for the system to handle the WCF queued tasks if the CPU is handling other inner tasks.

  1. Is it possible to change the Threadpool that WCF uses to a different one?
  2. Is it possible to manually change the task queue (global task queue, local task queue).
  3. Is it possible to manually handle 2 task queues that behave differently ?

Any help in the subject would be appropriated.

Gilad.

A: 

Since you are using .NET 4.0, you could run your long running processes through the TPL. By default, the TPL uses the .NET thread pool to execute tasks but you can also provide your own TaskScheduler implementation. Take a look at the example scheduler implementations in the samples for the TPL. I have not used it personally, but the QueuedTaskScheduler seems to assign tasks to a queue and uses its own thread pool to process the tasks. You can use this to define the maximum amount of threads you want to use for your long running tasks.

Eric Hauser
A: 

Keep in mind that the ThreadPool harbors two distinct types of threads: worker threads and I/O completion threads. WCF requests will be serviced by I/O threads. Tasks that you run via ThreadPool.QueueUserWorkItem will run on worker threads. So in that respect the WCF requests and the other CPU tasks are working from different queues already.

Some of your performance issues may be caused by your ThreadPool settings. From MSDN:

The thread pool maintains a minimum number of idle threads. For worker threads, the default value of this minimum is the number of processors. The GetMinThreads method obtains the minimum numbers of idle worker and I/O completion threads. When all thread pool threads have been assigned to tasks, the thread pool does not immediately begin creating new idle threads. To avoid unnecessarily allocating stack space for threads, it creates new idle threads at intervals. The interval is currently half a second, although it could change in future versions of the .NET Framework. If an application is subject to bursts of activity in which large numbers of thread pool tasks are queued, use the SetMinThreads method to increase the minimum number of idle threads. Otherwise, the built-in delay in creating new idle threads could cause a bottleneck.

I have certainly experienced the above bottleneck in the past. There is a method called SetMinThreads that will allow you to change these settings. By the way, you mention setting thread priorites; however, I am not familiar with the mechanism for changing thread priorities of the ThreadPool. Could you please elaborate? Also, I've read that setting thread priorities can be fraught with danger.

Coding Horror : Thread Priorities are Evil

By the way, how many processors/cores is your machine running?

Dan Terry
I have used SetMinThreads that causes the Threadpool to generate more threads by default. This partly solves the problem but causes the process to have allot of threads active even when the load is very low. This doesn't fully solve the issue when there are allot of small tasks in the process that also blocks up the thread pool queue.By changing the thread priority it is possible to suppress all internal threads and give priority to the requests from the user but that is only possible if the Threadpool executed the task.Thread.CurrentThread.Priority = ThreadPriority.Highest
Gilad