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.
Dlaczego chcesz tak wiele wątków uruchomione w tym samym czasie? –
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