2013-01-10 4 views
7

インターバルプロセスのキューをロードしようとしています。言い換えれば、キューがあり、キュー内の各アイテムを個別の間隔で実行する必要があります。.Net最大並行タイマースレッド

私の問題は、一度に25以上のスレッドを実行できないようです。私は、デフォルトの最大スレッド数が32768の64ビットマシンで.Net 4.5を使用しています。

私のマシンで扱うことができるほど多くのスレッドを同時に実行させるにはどうすればいいですか?

class Program 
{ 
    static void Main(string[] args) 
    { 
     System.Threading.ThreadPool.SetMaxThreads(200, 200); 
     test t = new test(); 

     t.LoadUrls("http://www.google.com"); 

     while (1 == 1) 
     { 
      System.Threading.Thread.Sleep(1000);//refresh every 5 seconds 
      Console.WriteLine(System.Diagnostics.Process.GetCurrentProcess().Threads.Count); 
     } 
    } 


    public class test 
    { 

     public void LoadUrls(string url) 
     { 
      for (int i = 0; i < 100; i++) 
      { 
       System.Threading.Timer t = new System.Threading.Timer(new System.Threading.TimerCallback(RunInterval), url, 0, 1000); 
       Console.WriteLine("Loaded {0} feeds.", i); 
      } 
     } 
     private static void RunInterval(object state) 
     { 
      string url = state as string; 
      string data = ""; 

      using (System.Net.WebClient cl = new System.Net.WebClient()) 
      { 
       Console.WriteLine("getting data for " + url); 
       data = cl.DownloadString(url); 
      } 

      //do something with the data 

     } 
    } 
} 

このコードは、理論的には2秒ほど後に198個のスレッドを実行する必要があります。ここでは

は私の生産コードでの実際の問題を複製例のアプリです。

ところで、これは私のプロトタイプアプリで美しく機能しました。それはノードに書かれています。しかし、今、私はそれがC#で正常に動作させることはできません...

ANSWER: は問題がガベージコレクションで実際にだったし、すべてのスレッドプールの問題ではありませんでした。プールは私がそれに投げているすべてのスレッドをスプールできる以上のものです。トリックは、System.Threading.Timerの単一のパラメーターコンストラクターを使用することです。これにより、タイマーはセマフォーとして使用され、gcを回避します。

class Program 
{ 
    static void Main(string[] args) 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      test t = new test(); 
      t.url = "http://www.google.com?" + i; 
      System.Threading.Timer ti = new System.Threading.Timer(new System.Threading.TimerCallback(t.RunInterval)); 
      ti.Change(0, 1000); 
     } 

     while (1 == 1) 
      System.Threading.Thread.Sleep(int.MaxValue); 
    } 


    public class test 
    { 
     public string url { get; set; } 
     public void RunInterval(object state) 
     { 
      Console.WriteLine("getting data for " + this.url); 
      string data = ""; 

      using (System.Net.WebClient cl = new System.Net.WebClient()) 
      { 
       data = cl.DownloadString(this.url); 
      } 
     } 
    } 
} 

あなたはタイマーがGCによって収集されたいと思う理由を私は確かにないんだけど、ちょっと私が何を知っていますか。

+1

であなたは、同時に実行されているので、多くのスレッドをしたいのはなぜ? –

+0

これはポーリングサービス用です。指定された間隔でn個のフィードをポーリングする必要があります。私はファンシーキューシステムを作って、サービスごとに1つのフィードしかポーリングしない個別のサービスを実行できます。しかし、私はこのメタを作りたいと思います。私はプログラムがそれぞれのプロセスを開始したいと思います。 – Eulalie367

答えて

5

私のマシンが処理できるように、私のアプリを同時に多くのスレッドとして実行させるにはどうすればよいですか?

これは間違ったアプローチです。すべてのスレッドはコストがかかり、数百を作成し、システムは大幅に低下します。

あなたのコードはThreadPoolを使用しています。プールにはスレッド数を制限するアルゴリズムがあります。スリープ()時間を増やすと、さらにスレッドがいくつか表示されることがあります。

もっと直接的な方法は、ThreadPool.MinThreadsを設定することです。しかし、より少ないパフォーマンスを期待してください。

+0

それは高価ではありません...私は64GBのRAMを持っていますが、それは10MBを超えることはありません。私はすべての64GBを使用したい。 あなたの提案は何ですか? – Eulalie367

+0

また、使用可能なCPUの1%以上を使用することはありません。 – Eulalie367

+0

私はいくつかの提案を加えましたが、依然として間違ったアプローチです。 –

2

System.Threading.Timer

Use a TimerCallback delegate to specify the method you want the Timer to execute. The timer delegate is specified when the timer is constructed, and cannot be changed. The method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system.

によると、その後System.Threading.Threadpool

There is one thread pool per process. Beginning with the .NET Framework 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. A process can call the GetMaxThreads method to determine the number of threads. The number of threads in the thread pool can be changed by using the SetMaxThreads method. Each thread uses the default stack size and runs at the default priority.

関連する問題