使用IAsyncResult委派函数

时间:2018-05-23 08:46:29

标签: c# asynchronous delegates

我的任务是接管使用委托的旧代码。

SearchDelegate[] dlgt = new SearchDelegate[numSearches];
IAsyncResult[] ar = new IAsyncResult[numSearches];

然后执行循环以启动多个委托函数

for (int i = 0; i < numSearches; i++)
{
    ar[i] = dlgt[i].BeginInvoke(....);
}

然后执行定时循环以从ar对象获取结果。

一切似乎都很好。我遇到的问题是,有时这些委托功能中的一些可能需要3到4秒才能启动,如果计数超过10则更长。这是一个常见问题,还是我可以调整设置?

这是在IIS上运行的。我可以使用最少的机器资源在本地复制问题。

谢谢大家。

哈根达斯

2 个答案:

答案 0 :(得分:1)

  

可能需要3到4秒才能启动

是由线程池引起的。当所有线程都忙时,它只会缓慢(2 /秒)创建新线程。

你可以提高池中的最小线程数量,但对于Web应用程序,你应该广泛研究,测试和测量。 ASP.NET也是线程池中的一个大利益相关者。

答案 1 :(得分:0)

BeginInvoke方法将实际工作分派给线程池,因为它已在此article中编写。实际上,当没有可用的空闲线程时,可能需要一些时间。线程池可能决定等待某些工作项完成或添加其他线程,会计最小和最大限制。

可以在The managed threadpoolSimple description of worker and IO threads in net以及本文的备注部分ThreadPool.SetMinThreads找到一些其他信息。

您应该知道相同的线程池用于HTTP请求处理,因此将自定义的非IO绑定工作卸载到Web应用程序中的线程池通常是毫无意义的,因为它不会给你任何好处,甚至可能因为额外的线程切换而损害性能。虽然BeginInvoke看起来不像是异步IO操作的调用。

实际上哪个具体线程执行工作并不重要 - 客户端仍然需要等待响应相同的时间。看起来像你可能一样,可能通过并行执行工作赢得一些时间,但只要在线程池中没有可用的线程来处理HTTP请求和你的负载,它就不可能在负载下运行。定制工作项目。

您可以查看此thread以获取有关此主题的其他详细信息。它与Task相关,但只要BeginInvokeTask.Run在引擎盖下使用相同的线程池,这并不重要。