Ich lerne gerade C# und ich habe in den letzten zwei Tagen an einem XML-Parser gearbeitet. Es funktioniert wirklich gut mein Problem ist die Zeit, die es dauert, mehr als 10k Seiten zu parsen. Das ist mein Code.C# Starten aller Threads in der gleichen Zeit beim Parsen
public static void startParse(int id_min, int id_max, int numberofthreads)
{
int start;
int end;
int part;
int threadnbrs;
threadnbrs = numberofthreads;
List<Thread> workerThreads;
List<string> results;
part = (id_max - id_min)/threadnbrs;
start = id_min;
end = 0;
workerThreads = new List<Thread>();
results = new List<string>();
for (int i = 0; i < threadnbrs; i++)
{
if (i != 0)
start = end + 1;
end = start + (part);
if (i == (threadnbrs - 1))
end = id_max;
int _i = i;
int _start = start;
int _end = end;
Thread t = new Thread(() =>
{
Console.WriteLine("i = " + _i);
Console.WriteLine("start =" + _start);
Console.WriteLine("end =" + _end + "\r\n");
string parse = new ParseWH().parse(_start, _end);
lock (results)
{
results.Add(parse);
}
});
workerThreads.Add(t);
t.Start();
}
foreach (Thread thread in workerThreads)
thread.Join();
File.WriteAllText(".\\result.txt", String.Join("", results));
Console.Beep();
}
was ich eigentlich tun Splitting ein Bereich des Elements in verschiedenen Thread, der syntaktisch analysiert werden müssen, so dass jeder Thread-Handle X-Elemente.
für jeweils 100 Elemente dauert es ca. 20 Sekunden. aber ich brauchte 17 Minuten, um 10 0000 Elemente zu parsen.
Was ich brauche, ist jeder Thread, der gleichzeitig an 100 dieser 10 000 Elemente arbeitet, so dass es in 20 Sekunden erledigt werden kann. Gibt es dafür eine Lösung?
Parse-Code:
public string parse(int id_min, int id_max)
{
XmlDocument xml;
WebClient user;
XmlElement element;
XmlNodeList nodes;
string result;
string address;
int i;
//Console.WriteLine(id_min);
//Console.WriteLine(id_max);
i = id_min;
result = "";
xml = new XmlDocument();
while (i <= id_max)
{
user = new WebClient();
// user.Headers.Add("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.0.3; ko-kr; LG-L160L Build/IML74K) AppleWebkit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30");
user.Encoding = UTF8Encoding.UTF8;
address = "http://fr.wowhead.com/item=" + i + "?xml";
if (address != null)
xml.LoadXml(user.DownloadString(new Uri(address)));
element = xml.DocumentElement;
nodes = element.SelectNodes("/wowhead");
if (xml.SelectSingleNode("/wowhead/error") != null)
{
Console.WriteLine("error " + i);
i++;
continue;
}
result += "INSERT INTO item_wh (entry, class, subclass, displayId, ,quality, name, level) VALUES (";
foreach (XmlNode node in nodes)
{
// entry
result += node["item"].Attributes["id"].InnerText;
result += ", ";
// class
result += node["item"]["class"].Attributes["id"].InnerText;
result += ", ";
// subclass
result += node["item"]["subclass"].Attributes["id"].InnerText;
result += ", ";
// displayId
result += node["item"]["icon"].Attributes["displayId"].InnerText;
result += ", ";
// quality
result += node["item"]["quality"].Attributes["id"].InnerText;
result += ", \"";
// name
result += node["item"]["name"].InnerText;
result += "\", ";
// level
result += node["item"]["level"].InnerText;
result += ");";
// bakcline
result += "\r\n";
}
i++;
}
return (result);
}
So dauert es 20 Sekunden, 100 Elemente zu analysieren ... wie erwarten Sie 1000x den Durchsatz zu erreichen, 1000 mal so viele Elemente in der gleichen Zeit zu analysieren? Threading bietet nicht nur auf magische Weise freie Rechenleistung oder Netzwerkbandbreite (wir haben keine Ahnung, was die Zeit für die 100 Elemente braucht). –
@JonSkeet - aber das Hinzufügen von Threads ermöglicht es ihnen, auf mehrere CPU-Kerne zuzugreifen, während lineares Arbeiten nur einen Kern maximal verwendet. Auf einer Multi-Core-Maschine korrelliert Threading mehr Kerne in das Verfahren. Stimme vollständig dem Problem hier ist die Zeit, um 100 Elemente zu analysieren, die massiv übermäßig ist. – PhillipH
@PhillipH Auf einem typischen modernen Computer mit, sagen wir, 8 Kernen, würden Sie maximal 7-8x beschleunigen, nicht 1000x. Als Nebenbemerkung werden andere Dinge schnell zum Engpass (wie Netzwerk- oder Festplatten-IO). Sie sollten besser Ihren Code profilieren, um herauszufinden, warum Ihre Analyse so lange dauert, und das stattdessen beheben. –