Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET任务性能,有1000个被阻止的任务_C#_.net_Multithreading - Fatal编程技术网

C# .NET任务性能,有1000个被阻止的任务

C# .NET任务性能,有1000个被阻止的任务,c#,.net,multithreading,C#,.net,Multithreading,我有一些.NET4代码需要知道网络请求是否/何时超时 以下代码是否会导致在每次任务运行时将新的线程添加到.NET线程池中,然后在任务退出时将其释放 var wait = new Task(() => { using (var pauseEvent = new ManualResetEvent(false)) pauseEvent.WaitOne(TimeSpan.FromMilliseconds(delay)); }).ContinueWith(action); w

我有一些
.NET4
代码需要知道网络请求是否/何时超时

以下代码是否会导致在每次任务运行时将新的
线程添加到.NET线程池中,然后在任务退出时将其释放

var wait = new Task(() =>
{
    using (var pauseEvent = new ManualResetEvent(false))
        pauseEvent.WaitOne(TimeSpan.FromMilliseconds(delay));
}).ContinueWith(action);
wait.Start()
表明这种方法可行,但对一般系统的性能有影响

如果是这样的话,您建议如何处理大量请求超时(突发时可能为1000超时)


在Python中,我以前使用过类似tornado iLoop的东西来确保这不会对内核/线程池造成太大的负担。

首先,向线程池添加任务并不一定会导致向线程池添加新线程。将新任务添加到线程池时,它将被添加到内部队列。线程池中的现有线程逐个从此队列中获取任务并执行它们。线程池将启动或停止新线程(视情况而定)

添加内部带有阻塞逻辑的任务将导致线程池中的线程阻塞。这意味着他们将无法执行队列中的其他任务,这将导致性能问题

向某些操作添加延迟的一种方法是使用Task.delay方法,该方法内部使用计时器

Task.Delay(delay).ContinueWith(action);
这不会阻止线程池中的任何线程。在指定的延迟之后,
操作
将被添加到线程池并执行

您也可以直接使用计时器

正如有人在评论中建议的,您也可以使用异步方法。我相信下面的代码与您的示例相当

public async Task ExecuteActionAfterDelay()
{
    await Task.Delay(3000);
    action();
}
你可能还想看看这个问题

我有一些.NET4代码需要知道网络请求是否/何时超时

最简单的方法是在API级别使用超时,例如,
WebRequest.timeout
CancellationTokenSource.CancelAfter
。这样,当超时发生时,操作本身将实际停止并出现错误。这是执行超时的正确方法

进行定时等待是完全不同的。(您的代码执行定时等待)。对于定时等待,只有等待超时;操作仍在继续,消耗系统资源,不知道应该停止

如果必须对
WaitHandle
执行定时等待,如
ManualResetEvent
,则可以使用,它允许线程池线程一次等待31个对象,而不是一个对象。但是,我认为这是一个最后的极端解决方案,如果代码不能被修改以使用适当的超时,则只能接受。 补充说明:增加了对.NET 4的
async
/
wait
支持


p.p.S.在未明确指定计划程序的情况下,切勿使用
StartNew
ContinueWith
。正如我在博客中所描述的那样,.

您可以使用异步api来处理网络请求。在这种情况下,强烈建议使用
async
wait
API。它们是使用联合例程实现的,并且比您在这里所做的要轻得多。虽然我使用的是
net4
,而且我相信它们确实是在
.net4.5
中引入的,但据我所知,向线程池添加许多阻塞的任务可能会导致许多新线程加速。AFIK
任务。延迟
异步
/
等待
中不可用。net4
启动任务不会将
任务
添加到
线程池
。任务可以由线程池中的线程执行,但情况并非总是如此。感谢您提供全面的答案和文章链接。我在应用层网络领域,所以这不是一个简单的网络请求。请求(在大多数情况下)将始终完成,但几秒钟后,将触发从远程推送回客户端
ThreadPool.RegisterWaitForSingleObject
看起来不错,但如果可能,我会避免。你从哪里得到的
31
数字?@John:有一个Win32 API,允许一个线程最多等待32个句柄。一个用于线程控制(添加/删除句柄或终止线程),每个线程池线程保留31个句柄。