所以,我追查了这个问题,但我不明白根本原因,我很好奇。
我有多个线程从本地驱动器读取文件(有时是同一个文件,但通常是不同的文件。这似乎无关紧要)。这是测试设置,但在生产中,这些文件是从 Web 服务器检索的。
无论如何,我注意到,在调用 之后ThreadPool.SetMaxThreads()
,我收到了读取这些文件的超时。删除那条线会使问题消失。我的直觉是它与设置异步 IO 线程的数量(completionPortThreads
第二个参数)有关,但即使我将该值设置为一个很大的数字(50、100、...),问题仍然存在。
删除对SetMaxThreads
“修复”问题的调用,尽管这意味着我不能增加或减少用于测试目的的线程数。
这是重现该问题的代码块。文件大小无关紧要,因为我的测试文件范围从 2KB 到 3MB。
class Program
{
static void Main(string[] args)
{
_count = 15;
// Comment this line out and everything works
ThreadPool.SetMaxThreads(13, 50);
using (var mre = new ManualResetEvent(false))
{
for (int i = 0; i < _count; ++i)
{
ThreadPool.QueueUserWorkItem(ThreadFunc, mre);
}
mre.WaitOne();
}
}
private static readonly ConcurrentStack<byte[]> _files = new ConcurrentStack<byte[]>();
private static int _count;
private static void ThreadFunc(object o)
{
const string path = @"SomeLocalFile";
var file = ReadFile(path);
_files.Push(file);
if (Interlocked.Decrement(ref _count) == 0)
{
((ManualResetEvent)o).Set();
}
}
private static byte[] ReadFile(string uri)
{
var request = WebRequest.Create(uri);
using (var response = request.GetResponse())
using (var stream = response.GetResponseStream())
{
var ret = new byte[stream.Length];
stream.Read(ret, 0, ret.Length);
return ret;
}
}
}
所以,是的,不知道这里发生了什么。即使 IO 线程的值很大,我也会在每次测试中超时。我当然错过了一些东西。