C# yüksek performanslı crawler yazılı olması, açıkça yönetmek onlarca veya iş parçacığı yüzlerce gitmek için en iyi yol değildir, bazı yetki ile söyleyebiliriz. Bu yapılabilir (yaptım), ama aşırı acı verici.
Bu, dedi. . .
Başvurunuz bence şekilde yazılmışsa, o zaman her iplik böyle bir şey yapar:
while (!Shutdown)
{
// get next url to crawl from somewhere
// download the data from that url
// do something with the data
}
yüklemeler arasındaki konuları duraklatma oldukça kolaydır. İki ManualResetEvent
örneğini yapmanızı öneririm: biri devam etmek için, diğeri ise kapanma için. Tüm paletli iplikleri erişebilmesi böylece bu static
şunlardır:
static ManualResetEvent ShutdownEvent = new ManualResetEvent(false);
static ManualResetEvent ContinueEvent = new ManualResetEvent(true);
Daha sonra, her bir iplik bir döngüde WaitAny
kullanır: I handles
dizi tanımlı zaman, ilk ShutdownEvent
belirtilen
WaitHandle[] handles = new WaitHandle[] { ShutdownEvent, ContinueEvent };
while (true)
{
int handle = WaitHandle.WaitAny(handles); // wait for one of the events
if (handle == -1 || handle >= handles.Length)
{
throw new ApplicationException();
}
if (handles[handle] = ShutdownEvent)
break; // shutdown was signaled
if (handles[handle] == ContinueEvent)
{
// download the next page and do something with the data
}
}
not edin. Bunun nedeni, birden çok öğenin sinyal vermesi durumunda, WaitAny
, sinyalli bir nesneye karşılık gelen en düşük endeksi döndürmesidir. Dizi diğer sırada doldurulmuşsa, önce duraklamadan kapanamayacaksınız.
Şimdi, iş parçacığının kapanmasını istiyorsanız, ShutdownEvent.Set
numaralı telefonu arayın. Ve iş parçacığının duraklatılmasını istiyorsanız, ContinueEvent.Reset
numaralı telefonu arayın. Konuların devam etmesi için, ContinueEvent.Set
numaralı telefonu arayın.
Bir indirme işleminin ortasında duraklamak biraz daha zor. Bunu yapmak mümkündür, ancak sorun, çok uzun bir süre duraklatırsanız sunucu zaman aşımı olabilir. Ve sonra indirmeyi en baştan yeniden başlatmanız gerekecek ya da sunucu ve kodunuz destekliyorsa, indirme işlemini bıraktığınız noktadan yeniden başlatın. Her iki seçenek de oldukça acı verici, bu yüzden bir indirme işleminin ortasında durmaya çalışmanızı öneriyorum.
Yararlı bir yanıt gibi bir şey istiyorsanız, biraz daha fazla bilgi vermeniz gerekir. Bu konuları ne yapıyor? Nasıl başlıyorlar? Hangi koşullar altında "duraklatıldı"? Daha fazla bilgi olmadan, bu soruyu cevaplamak imkansız. –
Bir işlemdeki 500 iş parçacığı, özellikle bir demet zamanın çoğunda uyuyorsa, çok fazla sayıda * iş parçacığı sayısıdır. Tavsiyem, mimarinizi makinede işlemciler olduğundan daha fazla iş parçacığı kullanacak şekilde yeniden tasarlamaktır. İplikler C# içinde çok "ağır"; İşi yapmak için gerekli olan mutlak minimum değeri oluşturmalısınız. Ne yapıyorsun o kadar çok iş parçacığı yaratıyorsun? –
Bu bir web tarama uygulamasıdır. Her iş parçacığı, çoğu web sunucusundan yanıt beklerken zamanının çoğunu geçirir, tüm iş parçacıkları aynı yerde başlatılır ve kullanıcı "duraklat" düğmesine bastığında duraklatılmalıdır. Uygulama genellikle 700m-2G bellek alır ve bunu yapmak için daha iyi bir yol olmadığı sürece bununla tamamım; 500 iş parçacığında bile, uygulama genellikle –