从WCF服务启动多个任务

Mar*_*scu 22 c# multithreading task-parallel-library

我需要优化WCF服务......这是一件非常复杂的事情.这次我的问题与任务有关(Task Parallel Library,.NET 4.0).发生的事情是我在调用服务(使用Task.Factory.StartNew)时启动了几个任务,然后等待它们完成:

Task.WaitAll(task1, task2, task3, task4, task5, task6);
Run Code Online (Sandbox Code Playgroud)

好吧......我看到,不喜欢的是,在第一次通话时(有时前2-3次通话,如果一个接一个地快速完成),最后的任务比其他任务开始得晚(我正在寻找)在其他人开始后0.5秒开始的情况下).我试着打电话

ThreadPool.SetMinThreads(12*Environment.ProcessorCount, 20);
Run Code Online (Sandbox Code Playgroud)

在我的服务开始,但它似乎没有帮助.

这些任务都与数据库相关:我正在从多个数据库中读取数据,并且必须花费尽可能少的时间.

知道为什么最后一项任务花了这么长时间吗?有什么我可以做的吗?

或者,我应该直接使用线程池吗?事实上,在我看到的一个案例中,一个任务在最后一个任务开始之前已经结束 - 如果我重新使用该线程而不是等待创建新线程,我将节省0.2秒.但是,我不能肯定任务将最后总是这么快,所以我不能把两个请求在相同的任务.

[编辑]操作系统是Windows Server 2003,因此不应该有连接限制.此外,它托管在IIS中 - 我不知道我是应该创建常规线程还是使用线程池 - 这是首选版本?

[编辑]我也尝试过使用Task.Factory.StartNew(action, TaskCreationOptions.LongRunning);- 它没有帮助,最后一项任务仍然比其他任务开始的时间晚了很多(大约半秒钟后).

[编辑] MSDN 1说:

在启动新的空闲线程之前,线程池具有内置延迟(.NET Framework 2.0版中的半秒).如果您的应用程序在短时间内定期启动许多任务,则空闲线程数量的少量增加可以显着提高吞吐量.将空闲线程数设置得太高会不必要地消耗系统资源.

但是,正如我所说的,我已经在调用SetMinThreads并且它没有帮助.

Ted*_*sen 7

使用(.Net 4.0)Task-object时,我自己遇到了线程启动延迟的问题.所以对于时间要求严格的东西,我现在使用专用线程(......再次,因为这是我在.Net 4.0之前所做的.)

线程池的目的是避免启动和停止线程的操作系统成本.线程只是被重用.这是在例如互联网服务器中发现的常见模型.优点是他们可以更快地做出反应.

我编写了许多应用程序,通过让专用线程从任务队列中获取任务来实现我自己的线程池.但请注意,这通常需要锁定,这可能会导致延迟/瓶颈.这取决于你的设计; 任务很小然后会有很多锁定,交换一些CPU可能会更快,以减少锁定:http://www.boyet.com/Articles/LockfreeStack.html

SmartThreadPool是.Net线程池的替换/扩展.正如您在此链接中所看到的,它有一个很好的GUI来进行一些测试:http://www.codeproject.com/KB/threads/smartthreadpool.aspx

最后,它取决于您的需求,但为了获得高性能,我建议您实现自己的线程池.如果你经历了很多线程空闲,那么增加线程数可能是有益的(超出推荐的cpucount*2).这实际上是HyperThreading在CPU内部的工作方式 - 在执行其他操作的操作时使用"空闲"时间.

请注意,.Net具有每个进程25个线程的内置限制(即,对于您同时收到的所有WCF调用).此限制是独立的,并且会覆盖ThreadPool设置.它可以增加,但它需要一些魔术:http://www.csharpfriends.com/Articles/getArticle.aspx? articleID = 201


小智 1

操作系统是什么?如果您没有运行 Windows 服务器版本,则存在连接限制。由于连接限制,您的许多线程可能正在被序列化。

另外,我还没有使用任务并行库,但我有限的经验是,在网络环境中创建新线程很便宜。