我的應用程序必須連接到API並下載大約1200個項目。由於API的工作原理,我無法一次詢問所有項目,因此我必須爲每個項目發送一個查詢。項目很小,所以下載速度很快,如果我在短時間內發送太多請求(每2-3秒發出100個請求),服務器會阻止我(4-5秒)。我不希望服務器每次都阻止我的應用程序大約10-12次,所以我決定實現一個減速目標,另一個線程只需要休眠0.4秒,並且工作人員將加入它,所以如果工作人員完成每個線程下載0.4秒大關它會等待之前,如果它完成後,將直接進入下一個如何在BackgroundWorker中啓動線程?
期望的實現:
private void DownloadLibrary_DoWork(object sender, DoWorkEventArgs e)
{
int max = 1200;
int slowdown = 400; // milliseconds
Thread methronome = new Thread(() => Thread.Sleep(slowdown));
for (int i = 0; i < max; i++)
{
methronome.Start();
DownloadItem(i);
WorkerDownloadLibrary.ReportProgress((int)i/max, string.Format("Dowloaded item {0} out of {1}", i+1, max));
methronome.Join();
}
}
private void UserClickStart(object sender, RoutedEventArgs e)
{
System.Windows.MessageBox.Show("Let's start!");
WorkerDownloadLibrary.RunWorkerAsync();
}
private void DownloadLibrary_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Windows.MessageBox.Show("Completed!");
}
的問題是,如果我這樣做,後臺工作者提前結束(RunWorkerCompleted執行),如果我同時註釋methronome.Start()
和methronome.Join()
這兩行,它會按預期工作,但當然會結束不時被封鎖。 我做錯了什麼?
我可以直接在BackgroundWorker的執行等待,因爲下載的速度非常快,無論如何,但似乎仍然不好而設計的,它會慢一個緩慢的電腦上太多。
工作,但落實緩慢:
private void DownloadLibrary_DoWork(object sender, DoWorkEventArgs e)
{
int max = 1200;
int slowdown = 400; // milliseconds
for (int i = 0; i < max; i++)
{
DownloadItem(i);
WorkerDownloadLibrary.ReportProgress((int)i/max, string.Format("Dowloaded item {0} out of {1}", i+1, max));
Thread.Sleep(slowdown);
}
}
還有另一種方式來做到這一點:將所有查詢一個接一個,然後等待服務器塊只有當,但看起來很糟糕通過設計,當下載每2秒停止一次時,用戶就會頭暈目眩。而服務器可能會阻止我永遠如果我這樣做總是
工作,但普通的壞實現
private void DownloadLibrary_DoWork(object sender, DoWorkEventArgs e)
{
int max = 1200;
int slowdown = 5000; // milliseconds
string serverResponse;
for (int i = 0; i < max; i++)
{
do
{
serverResponse = DownloadItem(i);
if (serverResponse != "OK")
Thread.Sleep(slowdown);
} while (serverResponse != "OK") ;
WorkerDownloadLibrary.ReportProgress((int)i/max, string.Format("Dowloaded item {0} out of {1}", i+1, max));
}
}
我如何能實現第一個選項?
你有沒有試過用秒錶來一次你下載的執行,然後等待剩餘毫秒?這將是你的**工作的改進版本,但執行速度很慢**。使用額外的線程來做時間似乎對我來說過分。 – jessehouwing 2014-10-05 12:09:47
您也可以嘗試讓數據提供商提供批量查詢選項,如果您要經常查詢它們,也可能會使它們更加快樂。 – jessehouwing 2014-10-05 12:10:52
@BartoszKP它並不打算快。我解釋了這個問題:如果應用程序運行速度太快,API服務器會阻止我。這樣用戶可以看到「流暢」的下載,即使速度很慢。 @jessehouwing好主意!我會嘗試'秒錶'。關於詢問數據提供者,他們並不太在意API,文檔很糟糕,我過去要求提供技術問題,但他們的回答總是含糊不清而且沒用。我可以向你保證,他們不會把資源用於改進他們的API。也許將來當我的應用程序完成時,我會問他們關於「批量」選項 – 2014-10-05 12:17:22