2013-10-12 79 views
0

我需要將多個HTML頁面作爲字符串下載並存儲到列表中。但隨後需要按照我開始下載的順序進行存儲。目前該列表按照下載完成的順序進行。所以當下載完成時,它的內容被添加到列表中。但他們不一定按照他們開始的順序完成。而且即時通訊有點難以理解如何將這些數據按照它們啓動的順序存儲在列表中。DownloadStringAsync維護訂單的多個URL

這是我目前的代碼,這啓動了下載序列。 URLList是一個網址列表,我需要下載的字符串是相同的順序,因爲這最初的名單:

cts = new CancellationTokenSource(); 
try 
{ 
    await AccessTheWebAsync(cts.Token); 
    listBox1.DataSource = VideoList; 
} 
catch (Exception) 
{ 
    MessageBox.Show("\r\nDownload failed.\r\n"); 
} 
cts = null; 

然後調用下面的代碼:

async Task AccessTheWebAsync(CancellationToken ct) 
{ 
    HttpClient client = new HttpClient(); 
    client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"); 

    IEnumerable<Task<string>> downloadTasksQuery = from url in URLList select ProcessURL(url, client, ct); 

    List<Task<string>> downloadTasks = downloadTasksQuery.ToList(); 

    while (downloadTasks.Count > 0) 
    { 
     Task<string> firstFinishedTask = await Task.WhenAny(downloadTasks); 

     downloadTasks.Remove(firstFinishedTask); 

     string length = await firstFinishedTask; //this is the data of the first finished download 
     int refPoint = length.IndexOf("Download (Save as...): <a href=\"") + 32; 
     VideoList.Add(length.Substring(refPoint, length.IndexOf("\">", refPoint) - refPoint)); 
    } 
} 

async Task<string> ProcessURL(string url, HttpClient client, CancellationToken ct) 
{ 
    HttpResponseMessage response = await client.GetAsync(url, ct); 
    string urlContents = await response.Content.ReadAsStringAsync(); 
    return urlContents; 
} 

我敢肯定它的東西,而簡單。但我只需要下載的字符串與原始URLList列表的順序相同。任何幫助將非常感激。

回答

0

未測試,但這應該工作。

async Task AccessTheWebAsync(CancellationToken ct) 
{ 
    HttpClient client = new HttpClient(); 
    client.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)"); 

    var downloadTasks = new List<Task<Tuple<string, int>>(); 

    int index = 0; 
    foreach(var url in URLList) 
     downloadTasks.Add(ProcessURL(url, client, ct, index++)); 

    while (downloadTasks.Count > 0) 
    { 
     Task<Tuple<string, int>> firstFinishedTask = await Task.WhenAny(downloadTasks); 

     downloadTasks.Remove(firstFinishedTask); 

     Tuple<string, int> result = await firstFinishedTask; //this is the data of the first finished download 
     int refPoint = result.Item1.IndexOf("Download (Save as...): <a href=\"") + 32; 
     VideoList.Add(length.Item1.Substring(refPoint, length.IndexOf("\">", refPoint) - refPoint)); 
    } 
} 

async Task<Tuple<string, int>> ProcessURL(string url, HttpClient client, CancellationToken ct, int index) 
{ 
    HttpResponseMessage response = await client.GetAsync(url, ct); 
    string urlContents = await response.Content.ReadAsStringAsync(); 
    return Tuple.Create(urlContent, index); 
} 
+0

我試過你的代碼,但得到一些錯誤,我修正了1但不知道如何修復其他。我對C#仍然很陌生。它的行「字符串長度=等待firstFinishedTask;」 – Calpulz

+0

我更新了代碼。 result.Item2包含下載任務的索引。 –

+0

工作過,謝謝你的時間和精力<3 – Calpulz