WebClient seltsames Timing-Verhalten
Datum: 07.05.2009 22:08
Message-ID: <20090507220854.0a93f4de@schabi.de>
Newsgroup: de.comp.os.ms-windows.programmer
Hallo,
Wieder mal ein seltsames Verhalten, das ich auf einen Minimaltest
reduziert habe:
WebClient scheint beim Zugriff auf "file://" URLs ein seltsames
verhalten zu zeigen - der Zugriff scheint seltsam verzögert.
Das Programm:

using System;
using System.IO;
using System.Net;
using System.Threading;
namespace FileTest
{
class Program
{
const int MAX=10;
static readonly string basepath = new DirectoryInfo("Testfiles").FullNa
me;
static readonly string baseurl = "file://"+basepath.Replace('\\','/');
static volatile int count=0;
static void ReadWithWebClient(object number) {
using (WebClient w = new WebClient()) {
string url = baseurl+"/File"+number+".txt";
using (StreamReader r = new StreamReader(w.OpenRead(url))) {
Console.WriteLine(number+ " \tweb: " + r.ReadLine());
}
}
}
static void ReadWithFile(object number) {
using (StreamReader r = new StreamReader("Testfiles\\File"+number+".tx
t")) {
Console.WriteLine(number + " \tfile: " + r.ReadLine());
}
}
static void TimeAction(string message, WaitCallback method, object number
) {
DateTime start = DateTime.Now;
method(number);
TimeSpan duration = DateTime.Now - start;
Console.WriteLine(number + " \t" + message + " duration: " +
duration.To
talSeconds);
Interlocked.Increment(ref count);
}
public static void Main(string[] args)
{
createFiles();
Console.WriteLine(baseurl);
for (int i=0; i < MAX; i+=1) {
ThreadPool.QueueUserWorkItem(
delegate(object number){
TimeAction("web", ReadWithWebClient, number);
},
i);
ThreadPool.QueueUserWorkItem(
delegate(object number){
TimeAction("file", ReadWithFile, number);
},
i);
Thread.Sleep(0); // Hier...
}
while (count<2*MAX)
Thread.Sleep(1000);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
static void createFiles()
{
Directory.CreateDirectory("Testfiles");
for (int i = 0; i < MAX; i += 1) {
string name = "Testfiles\\File" + i.ToString() + ".txt";
if (!File.Exists(name)) {
using (StreamWriter writer = new StreamWriter(name)) {
writer.WriteLine("Hallo");
}
}
}
}
}
}
Theoretisch würde man erwarten, dass beide Methoden die Files in
praktisch Nullzeit einlesen.
Tatsächlich scheint sich die WebClient.OpenRead jedoch Zeit zu lassen,
und auf weitere OpenReads zu warten.
Wenn ich den Thread.Sleep(0); beim "Hier" auf 100 erhöhe, ist die
erste
web.duration 0.015625, und alle weiteren 0, das ganze läuft ziemlich
schnell durch. Aber schon beim Wert 10 zeigt sich ein seltsames
Verhalten, das untere Logfile ist beim Wert 0 entstanden:
0 file: Hallo
0 file duration: 0,015625
1 file: Hallo
1 file duration: 0
2 file: Hallo
2 file duration: 0
3 file: Hallo
3 file duration: 0
4 file: Hallo
4 file duration: 0
5 file: Hallo
5 file duration: 0
6 file: Hallo
6 file duration: 0
7 file: Hallo
7 file duration: 0
8 file: Hallo
8 file duration: 0
9 file: Hallo
9 file duration: 0
1 web: Hallo
1 web duration: 5,984375
2 web: Hallo
6 web: Hallo
6 web duration: 3
2 web duration: 5
5 web: Hallo
5 web duration: 3,5
0 web: Hallo
0 web duration: 6
7 web: Hallo
7 web duration: 2,5
3 web: Hallo
3 web duration: 4,515625
4 web: Hallo
4 web duration: 4,015625
9 web: Hallo
9 web duration: 1,015625
8 web: Hallo
8 web duration: 2,015625
Dass die "file"-Outputs in etwa im Sekundentakt auftauchen, liegt wohl
daran, dass der Threadpool, wenn er busy ist, in etwa in diesem Takt
neue Threads anlegt - das ist so dokumentiert.
Das deutet alles drauf hin, dass die WebClient-Methode eine bestimmte
Zeit wartet, ob noch weitere Requests kommen, und in diesem Fall noch
länger wartet, bevor sich was tut.
In unserem etwas komplexeren realen Programm auf Vista64 laufen sogar
einige der WebClients in eine TimeoutException!
Hat jemand eine Erklärung oder Lösung dafür?
Danke,
Markus
--
"A patched buffer overflow doesn't mean that there's one less way
attackers can get into your system; it means that your design process
was so lousy that it permitted buffer overflows, and there are probably
thousands more lurking in your code." - Bruce Schneier
[ Auf dieses Posting antworten ]
