1

我第一次在一个项目中使用 ThreadPools,并且需要能够在 main 方法的两个不同部分中对工作项进行排队。我制作了这个简单的示例进行测试,并且在对象创建行的任一 for 循环中不断收到 OutOfMemoryException。是否需要在线程执行结束时执行某种清理以释放该线程占用的任何内存?如果不是,我该如何解决我的内存问题?

class Program
{
    public static HashSet<String> domains;
    static void Main(string[] args)
    {
        //Static DB Connection
        //Database Set
        domains = new HashSet<string>();
        while (true)
        {
            //Pull Data From The Database
            String[] chars = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" };
            for (int i = 0; i < 10; i++)
            {
                Loader l = new Loader(chars[i]);
                if (!domains.Contains(chars[i]))
                {
                    lock (domains)
                    {
                        domains.Add(chars[i]);
                    }
                    ThreadPool.QueueUserWorkItem(new WaitCallback(l.ThreadPoolCallback), i);
                }

            }
           for (int i = 0; i < 10; i++)
            {
                Parser p = new Parser();
                ThreadPool.QueueUserWorkItem(new WaitCallback(p.ThreadPoolCallback), i);
            }
        }
    }
}

解析器类:

 class Parser
{
    public void ThreadPoolCallback(Object threadContext)
    {
        ManualResetEvent eventx = new ManualResetEvent(false);
        //int threadIndex = (int)threadContext;
        Console.WriteLine("Parser Thread: " + threadContext);
        eventx.Set();
    }
}

装载机类:

class Loader
{
    String ch { set; get; }
    public Loader(String new_ch)
    {
        ch = new_ch;
    }
    public void ThreadPoolCallback(Object threadContext)
    {
        ManualResetEvent eventx = new ManualResetEvent(false);
        Console.WriteLine("Added " + this.ch + " to " + Thread.CurrentThread.GetHashCode());
        //int threadIndex = (int) threadContext;
        //Console.WriteLine("Loader Thread: " + threadContext + " " + ch + "  " + Thread.CurrentThread.GetHashCode());
        lock(Program.domains)
        {
            Program.domains.Remove(this.ch);
            Console.WriteLine("Removed " + this.ch + " from " + Thread.CurrentThread.GetHashCode());
        }
        eventx.Set();
    }

}

谢谢一堆。

编辑感谢所有的帮助。我现在看到了我所犯的错误

4

3 回答 3

2

你有一个无限的while循环,除了吐出新线程之外什么都不做。线程占用大量内存(32 位为 1MB;64 位为 4MB),因此如果您不先耗尽线程限制,最终您将耗尽内存。

另外——您对 ManualResetEvent 的使用不正确。它需要在方法范围之外创建,否则它什么也做不了(因为每个进入方法的线程都会创建一个新的 resetevent 对象实例;为了同步,线程必须访问同一个对象)。

于 2012-06-27T22:28:44.767 回答
2

尽管线程池限制了线程数,但您的循环不会限制队列中用户工作项的数量。您的无限循环将耗尽内存。

于 2012-06-27T22:33:43.877 回答
1

就像 roken 说的,字里行间的一切

while(true)
{
   ....
}

正在无限重复。

于 2012-06-27T22:31:11.250 回答