한 번에 여러 스레드를 실행하고 싶습니다 (예 : 최대 5 개의 스레드). 둘 중 하나가 완료되면 새 스레드가 다른 데이터로 시작됩니다. (하나의 완료, 하나의 새로운 시작, 두 개의 완료, 두 개의 새로운 시작 ...)
Main for 루프는 기본 폼에 있지만 UI를 차단하지 않는 다른 스레드에서 실행됩니다.세마포어가 여러 스레드에서 작동하지 않는 것 같습니다.
실행하면 시각적으로 5 개의 웹 브라우저 컨트롤이 추가되고 페이지로드가 완료되면로드 된 컨트롤이 제거됩니다.
문제가 더 이상 폼에 추가되지 않습니다.
새 기능이 시작될 수 있도록 세마포가 제대로 릴리스되지 않았거나 다른 기능이 누락 되었습니까?
그리고 프로그램을 종료해도 종료되지 않고 계속 수행해야 할 작업이 많기 때문에 WaitHandle.WaitOne에서 차단됩니다.
더 많은 코드 명확성을 위해 불필요한 데이터를 일부 제거했습니다.
Semaphore pool = new Semaphore(5, 5);
Scraper[] scraper = new Scraper[5];
Gecko.GeckoWebBrowser wb = null;
int j = 0;
for (int i = 0; i < arrScrapeboxItems.Count; i++)
{
pool.WaitOne();
bool pustiMe = true;
while (pustiMe)
{
if (scraper[j] == null) scraper[j] = new Scraper();
if (scraper[j].tred == null)
{
ScrapeBoxItems sbi = (ScrapeBoxItems)arrScrapeboxItems[i];
doneEvents.Add(new ManualResetEvent(false)); // this is for WaitHandle.WaitAll after the for loop is done all the items
wb = new Gecko.GeckoWebBrowser();
PoolObjects po = new PoolObjects();
po.link = sbi.link;
// etc...
scraper[j].ThreadsCompleted += new Scraper.ThreadsHandler(frmMain_NextThreadItemsCompleted);
scraper[j].tred = new Thread(new ParameterizedThreadStart(scraper[j].Scrape));
scraper[j].tred.Start(po);
pustiMe = false;
if (j == maxThreads - 1)
j = 0;
else
j++;
break;
}
else if (scraper[j].tred.IsAlive) // if the thread is finished, make room for new thread
{
scraper[j] = null;
}
if (pustiMe) Thread.Sleep(1000);
}
}
// event from Scraper class
void frmMain_ThreadsCompleted()
{
pool.Release();
}
그리고 스크레이퍼 클래스 모양 같은
:public void Scrape(object o)
{
po = (PoolObjects)o;
// do stuff with po
po.form.Invoke((MethodInvoker)delegate
{
po.form.Controls.Add(po.wb);
po.wb.DocumentCompleted += new EventHandler<Gecko.Events.GeckoDocumentCompletedEventArgs>(wb_DocumentCompleted);
po.wb.Navigate(po.link);
});
}
void wb_DocumentCompleted(object sender, Gecko.Events.GeckoDocumentCompletedEventArgs e)
{
var br = sender as Gecko.GeckoWebBrowser;
if (br.Url == e.Uri)
{
form.Controls.Remove(po.wb);
ThreadsCompleted();
manualReset.Set();
}
}
2 가지 가능한 문제처럼 보입니다. 새 스레드를 만들고 폼에 추가하는 대신 모든 스레드에 동일한 웹 브라우저를 사용하고 있습니다. 둘째로, 폼에서 웹 브라우저의 좌표와 크기를 지정하지 않습니다. 그들은 아마도 서로의 위에 있습니다. – TyCobb
@TyCobb 브라우저 객체를 for 루프 안으로 옮겼습니다.하지만 아무런 문제없이 같은 문제가있었습니다. 나는 브라우저 컨트롤을 수평으로 배치하기위한 코드를 가지고 있으므로 서로 위에 있지 않습니다. 뭔가 다른 문제가 있습니다. 답변 감사합니다. – lopkiju