2013-01-10 18 views
7

Próbuję załadować kolejkę procesów interwałowych. Innymi słowy, mam kolejkę i chcę, aby każdy element w kolejce działał w określonym przedziale czasu.. Maksymalna liczba równoczesnych wątków z timerem

Moim problemem jest to, że nie mogę uzyskać więcej niż 25 wątków do uruchomienia w tym samym czasie. Używam .Net 4.5 na maszynie 64-bitowej, która ma domyślną maksymalną liczbę wątków wynoszącą 32768.

Jak mogę uruchomić moją aplikację jako wiele równoczesnych wątków obsługiwanych przez mój komputer?

Oto przykład aplikacja, która replikuje rzeczywistego problemu w moim kodu produkcji:

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 

     } 
    } 
} 

Kod ten powinien teoretycznie uruchomić 198 wątków po 2 sekundach albo tak.

Nawiasem mówiąc, działało to pięknie w mojej prototypowej aplikacji; został napisany w węźle. Ale teraz nie mogę zmusić go do pracy prawidłowo w C# ...

ODPOWIEDŹ: Problemem było rzeczywiście ze zbierania śmieci i nie było w ogóle problem pula wątków; Pula jest bardziej niż zdolna do buforowania wszystkich wątków, które w nią rzucam. Sztuką jest użycie konstruktora pojedynczego parametru System.Threading.Timer; to sprawi, że timer sam się użyje jako semafora, unikając w ten sposób 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); 
      } 
     } 
    } 
} 

nie jestem na pewno, dlaczego kiedykolwiek chcesz timer być zbierane przez GC, ale hej, co ja wiem.

+1

Dlaczego chcesz tak wiele wątków uruchomione w tym samym czasie? –

+0

To jest dla usługi odpytywania. Musi odpytywać n kanałów w określonych odstępach czasu. Mogę stworzyć fantazyjny system kolejek i uruchomić pojedyncze usługi, które sondują tylko 1 kanał na usługę. Ale chciałbym uczynić to meta; Chciałbym, aby program rozpoczynał każdy indywidualny proces. – Eulalie367

Odpowiedz

5

Jak uruchomić aplikację w tylu jednoczesnych wątkach, które obsługuje moja maszyna?

To niewłaściwe podejście. Każdy wątek jest kosztowny, stwórz kilkaset, a Twój system poważnie się pogarsza.

Twój kod używa ThreadPool. Pula ma algorytm ograniczający liczbę wątków. Zwiększenie czasu uśpienia() może spowodować wyświetlenie jeszcze kilku wątków.

Bardziej bezpośredni sposób byłoby ustawić ThreadPool.MinThreads. Ale spodziewaj się mniejszej wydajności, a nie więcej.

+0

To nie jest takie drogie ... Mam 64 GB pamięci RAM do pracy, ale nigdy nie przekracza 10 MB.Chcę, żeby używał wszystkich 64 GB. Jaka byłaby Twoja sugestia? – Eulalie367

+0

Ponadto nigdy nie używa więcej niż 1% dostępnego CPU. – Eulalie367

+0

Dodałem kilka sugestii, ale nadal jest to niewłaściwe podejście. –

2

Według 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.

Następnie w 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.

Powiązane problemy