私にとって非常に重要なので、私はこの投稿でできる限り徹底的にしようとしています、
問題は非常に単純ですが、この質問のタイトルを読むだけで、アイデアを得ることができます...
質問は:
正常な帯域幅(30mb Vdsl)が利用可能です...
httpWebRequest
単一のデータ/ファイルに対して複数を取得するにはどうすればよいですか?、
したがって、各要求はデータの一部のみをダウンロード し、すべてのインスタンスが完了すると、すべての部分が1つの部分に結合されます。
コード:
...私がこれまでに取り組んできたのは、各タスク= HttpWebRequest =異なるファイルだけで、同じ考えです。
したがって、高速化は純粋なタスクの並列処理であり、複数のタスク/スレッドを使用した1回のダウンロードの高速化です。
私の質問のように。
以下のコードを参照してください
次の部分は、主題に関するより詳細な外植と背景だけです...あなたが読んでもかまわないのであれば。
私はまだこの(問題の)プロジェクトとは異なる同様のプロジェクトに取り組んでいますが、
それ(以下のコードを参照)が、別々のタスク(異なるダウンロード/ファイル)ごとにできるだけ多くの異なるデータソースをフェッチしようとした方法で。...したがって、各(タスク)が実行される機会を得る前に、前のタスクが最初に完了するのを待つ必要がない間に、スピードアップが得られました。
この現在の質問で私がやろうとしていること(以下のコードでほとんどすべての準備ができている)は、実際に は同じデータに対して同じURLをターゲットにしているので、今回は単一タスク(現在のダウンロード)を取得するためのスピードアップです。
今回のみ、以下のコードと同じアイデアを実装し、複数のインスタンスを使用して同じURLSmartWebClient
をターゲットにします。
次に(現時点では理論のみ)、データの部分的なコンテンツを要求し、インスタンスごとに複数の要求を行います。
最後の問題は、「パズルを1つの平和に戻す」必要があることです...私が知る必要がある別の問題...
このコードでわかるように、私がまだ作業できなかったのは、データの解析/処理だけで、非常に使いやすいhtmlAgilityPack
ので問題ありません。
現在のコード
メインエントリ:
var htmlDictionary = urlsForExtraction.urlsConcrDict();
Parallel.ForEach(
urlList.Values,
new ParallelOptions { MaxDegreeOfParallelism = 20 },
url => Download(url, htmlDictionary)
);
foreach (var pair in htmlDictionary)
{
///Process(pair);
MessageBox.Show(pair.Value);
}
public class urlsForExtraction
{
const string URL_Dollar= "";
const string URL_UpdateUsersTimeOut="";
public ConcurrentDictionary<string, string> urlsConcrDict()
{
//need to find the syntax to extract fileds names so it would be possible to iterate on each instead of specying
ConcurrentDictionary<string, string> retDict = new Dictionary<string,string>();
retDict.TryAdd("URL_Dollar", "Any.Url.com");
retDict.TryAdd("URL_UpdateUserstbl", "http://bing.com");
return retDict;
}
}
/// <summary>
/// second Stage Class consumes the Dictionary of urls for extraction
/// then downloads Each via parallel for each using The Smart WeBClient! (download(); )
/// </summary>
public class InitConcurentHtmDictExtrct
{
private void Download(string url, ConcurrentDictionary<string, string> htmlDictionary)
{
using (var webClient = new SmartWebClient())
{
webClient.Encoding = Encoding.GetEncoding("UTF-8");
webClient.Proxy = null;
htmlDictionary.TryAdd(url, webClient.DownloadString(url));
}
}
private ConcurrentDictionary<string, string> htmlDictionary;
public ConcurrentDictionary<string, string> LoopOnUrlsVia_SmartWC(Dictionary<string, string> urlList)
{
htmlDictionary = new ConcurrentDictionary<string, string>();
Parallel.ForEach(
urlList.Values,
new ParallelOptions { MaxDegreeOfParallelism = 20 },
url => Download(url, htmlDictionary)
);
return htmlDictionary;
}
}
/// <summary>
/// the Extraction Process, done via "HtmlAgility pack"
/// easy usage to collect information within a given html Documnet via referencing elements attributes
/// </summary>
public class Results
{
public struct ExtracionParameters
{
public string FileNameToSave;
public string directoryPath;
public string htmlElementType;
}
public enum Extraction
{
ById, ByClassName, ByElementName
}
public void ExtractHtmlDict( ConcurrentDictionary<string, string> htmlResults, Extract By)
{
// helps with easy elements extraction from the page.
HtmlAttribute htAgPcAttrbs;
HtmlDocument HtmlAgPCDoc = new HtmlDocument();
/// will hold a name+content of each documnet-part that was aventually extracted
/// then from this container the build of the result page will be possible
Dictionary<string, HtmlDocument> dictResults = new Dictionary<string, HtmlDocument>();
foreach (KeyValuePair<string, string> htmlPair in htmlResults)
{
Process(htmlPair);
}
}
private static void Process(KeyValuePair<string, string> pair)
{
// do the html processing
}
}
public class SmartWebClient : WebClient
{
private readonly int maxConcurentConnectionCount;
public SmartWebClient(int maxConcurentConnectionCount = 20)
{
this.Proxy = null;
this.Encoding = Encoding.GetEncoding("UTF-8");
this.maxConcurentConnectionCount = maxConcurentConnectionCount;
}
protected override WebRequest GetWebRequest(Uri address)
{
var httpWebRequest = (HttpWebRequest)base.GetWebRequest(address);
if (httpWebRequest == null)
{
return null;
}
if (maxConcurentConnectionCount != 0)
{
httpWebRequest.ServicePoint.ConnectionLimit = maxConcurentConnectionCount;
}
return httpWebRequest;
}
}
}
これにより、優れた帯域幅を利用できるようになります。対象となるソリューションからはほど遠いので、どこから始めればよいかについての手がかりを実際に利用できます。