Wenn du threading verwendest solltest du dir vorher wenigstens durchlesen was Racing conditions sind, wie Critical Sections (locks), Barriers, Mutexe, etc funktionieren. Ich weiß das in .Not Threading sehr einfach umzusetzen ist, das heißt aber trozdem nicht das es einfach ist. Bei Threading musst extrem aufpassen, denn fehler aufgrund von Racing Conditions zu finden ist extrem wiederlich (und z.T. extrem schwer bis unmöglich im debugger zu finden).
Ein einstieg dafür ist:
.
In deinem Fall muss ja nur das HTTP webrequest parallelisiert werden, der rest kostet ja keine Zeit. Das heißt man kann den restlichen code serialisieren, z.B. mit einer Barrier
Code:
Parallel.For(...
html = ...
barrier[i].SignalAndWait();
// no other of the working threads is currently running this section, and mainthread is also paused
...
retHorse.AddData(h);
barrier[i].SignalAndWait();
}); // for end
for (int i=0; i<barrier.length; i++) {
barrier[i].SignalAndWait(); // Wait for webrequrest
barrier[i].SignalAndWait(); // Wait for List addition
}
Du könntest auch eine Lock verwenden (ist wahrscheinlich sogar simpler) dabei kannst du aber nicht über das scheduling bestimmen. Mit Barriers übernimmt der Mainthread die aufgabe des Lock schedulings (was man eventuell haben möchte oder auch nicht). In diesem fall werden die threads aufsteigend gescheduled.
PS: Da eventuell exceptions auftreten können ist ein Try-Finally für die Barrier locks empfehlenswert