1

プロジェクトで初めて ThreadPools をいじっていますが、メイン メソッドの 2 つの異なるセクションで作業項目をキューに入れる必要があります。テスト用にこの簡単な例を作成しましたが、オブジェクト作成行のいずれかの 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

ローケンが言ったように、行間のすべて

while(true)
{
   ....
}

無限に繰り返されています。

于 2012-06-27T22:31:11.250 に答える