verwendete Web-Technologie: Silverlight und System.Net.Webclient
Hallo Leudde,
ich benutze die oben angegebene Technik um xml-Daten von einer Webseite zu laden. Die Seite habe ich mit php selbst gebaut und es funktioniert auch alles ganz toll.
Aber irgendwie werden die Daten nur beim ersten mal aufrufen von WebClient.OpenReadAsync() aktuell vom Server geholt.
Immer wenn ich die gleichen Zeilen Code nochmals ausführe (also innerhalb der Anwendung nicht durch neu start der Anwendung) dann bekomme ich das gleiche Ergebniss. Egal was sich in den xml-Daten auf dem Server geändert hat.
Ich lasse mir z.B. die Serverzeit in die XML schreiben aber es kommt nur beim ersten lesen die aktuelle Zeit. Jeder Aufruf dannach gibt die zuerst gelesenen Zeit zurück.
Wenn ich die gleiche Seite im Browser aufrufe bekomme ich jedesmal die neue aktuelle Serverzeit.
Gibts da irgendwie nen cache oder sowas?? Ich erzeuge auch in jeden lauf den WebClient neu mit "a = new WebClient()"
Howard
Hallo,
Wenn ich die gleiche Seite im Browser aufrufe bekomme ich jedesmal die neue aktuelle Serverzeit. Dann kann man ja die Serverseite schon mal ausschließen.
Wie verarbeitest Du die Daten denn von OpenReadCompleted-Event aus weiter?
Bist Du sicher, daß Du nicht selbst irgendwo ein veraltetes (das erste) Objekt benutzt?
Nebenbei:
Ich erzeuge auch in jeden lauf den WebClient neu mit "a = new WebClient()"
Dispose nicht vergessen! Am Besten in einen using
-Block einschließen.
Die Streams die Du beim OpenReadAsync erhätst, musst Du auch explizit mit Stream.Close
schließen..
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Okay ich habs mal versucht mit deinen Hinweisen aber es ändert sich nix.
hier mal der Quellecode
/// <summary>
/// holt die Daten von der Webseite. Wird von aussen auf TimerIntervall aufgerufen
/// </summary>
public void ReadData()
{
//using(WebClient actWebClient = new WebClient()) //funktionierte NICHT weil kein Dispose möglich
WebClient actWebClient = new WebClient();
{
actWebClient.OpenReadCompleted += WebClientOpenReadCompleted;
actWebClient.OpenReadAsync(new Uri(actURI));
}
}
/// <summary>
/// wenn alle Daten von der WebSeite geladen wurden
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void WebClientOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error != null)
{
this.LastError = e.Error.Message;
}
else
{
try
{
using (Stream s = e.Result)
{
XDocument doc = XDocument.Load(s);
......
s.Close();
}
}
catch (Exception ex)
{
this.LastError = ex.ToString();
}
}
}
Howard
Hallo,
funktionierte NICHT weil kein Dispose möglich
Klar, Du hast ja noch die asynchrone Operation laufen.
Dann solltest Du den WebClient in oder nach WebClientOpenReadCompleted disposen (da müsstest Du den Sender auf den WebClient casten können).
Am Quellcode kann ich auf Anhieb nix Böses entdecken. Schau doch mal auf dem Server, ob jedesmal eine Anfrage ankommt.
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
huhu,
häng Dir doch mall Fiddler dazwischen, dann siehst Du direkt, was der Client bzw. Server schickt.
😃
Xynratron
Herr, schmeiss Hirn vom Himmel - Autsch!
Die Erfahrung zeigt immer wieder, dass viele Probleme sich in Luft auslösen, wenn man sich den nötigen Abstand bzw. Schlaf gönnt.
Hai,
Hallo,
Dann solltest Du den WebClient in oder nach WebClientOpenReadCompleted disposen (da müsstest Du den Sender auf den WebClient casten können).
...
Gruß, MarsStein
also ich bekomme folgenden Compilerfehler wenn ich irgendwas mit Dispose versuche...auch beim Cast vom Sender
Fehlermeldung:
Fehler 3 "System.Net.WebClient" enthält keine Definition für "Dispose", und es konnte keine Erweiterungsmethode "Dispose" gefunden werden, die ein erstes Argument vom Typ "System.Net.WebClient" akzeptiert. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)
@Xynratron:
das mit dem Fiddler check ich gleich mal aus...
Howard
Also ich hab gerade mal die Fiddler Nummer ausprobiert...die iss ja ma rischtisch geil!!!
Danke mann da iss ne echt sinnvolle App....
Und mit der konnte ich sehen das meine App nur einmal beim Start eine Connection zur Website aufbaut.... und dannach nich mehr....hmm
also irgendwer chached da irgendwie irgendwas... nur wer??
Howard
Versuche mal Folgendes:
myClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
Gruß, Christian.
Hallo,
also ich bekomme folgenden Compilerfehler wenn ich irgendwas mit Dispose versuche
Seltsame Kiste... der WebClient ist AFAIK schon seit .NET 1.1 eine Component und erbt somit die Dispose-Methode.
Bei mir kompiliert und läuft auch folgender Testcode einwandfrei:
public static void Main()
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += (sender, e) =>
{
using(Stream s = e.Result)
{
StreamReader reader = new StreamReader(s);
Console.WriteLine(reader.ReadToEnd());
}
((WebClient)sender).Dispose(); // <--- bei mir läuft das so :-/
Console.WriteLine("");
Console.WriteLine("fertig.");
};
wc.OpenReadAsync(new Uri("http://www.mycsharp.de/"));
Console.WriteLine("gestartet\n");
Console.Read();
}
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
also wir reden hier von silverlight 4.0
ich weis ja nich was ihr so probiert habt aber ich hab hier weder nen Dispose noch nen CachePolicy....
Howard
okay ich hab ne Lösung gefunden...die iss zwar irgendwie Dirty aber sie funzed...scheint irgendwie nen Problem im Webclient oder so zu geben. Schaut mal hier
nachdem ich nun sowas wie "OpenReadAsync(new Uri(uri.AbsoluteUri + "?" + Guid.NewGuid().ToString())" eingetragen habe bekomm ich auch in Fiddler zu sehen und natürlich auch in meiner App das der connect nun funzed....
also irgendwas wird dort krass gechached....
Also wen noch einer ne andere Lösung also irgendwie nich gaaaanz so Dirty..wär ich dankbar ...aber ich komm auch damit klar... logisch muss ja nich gleich ne Guid sein kann ja auch nen random int sein
Howard
P.S: @TheBrainiac: Danke für dein Hinweis mit dem "CachePolicy" dadurch hab ich die richtige Seite Gogglen können 😁 👍
Hallo,
Also wen noch einer ne andere Lösung also irgendwie nich gaaaanz so Dirty..
Du könntest mal versuchen, den WebClient.Headers
ein
Cache-Control: no-cache
hinzuzufügen. Wenn das clientseitig nicht klappt, könntest Du das auch mal von der Serverseite aus versuchen.
Siehe RFC 2616: Cache-Control
Gruß, MarsStein
EDIT:
Auf der von Dir angegebenen Seite wird auch hierhin verlinkt:
Silverlight WebClient does not download updated resources
Dort wird als Lösung vorgeschlagen:
You can use something like webClient.Headers[HttpRequestHeader.IfModifiedSince] = "Sat, 19 Jul 2008 19:43:31 GMT"; (assuming webClient is the name of your WebClient instance, and the date is somewhere in the past)
Weiter unten ist dann auch noch die Rede von dem von mir erwähnten Cache-Control Header:
The cache policies are used by the Browser when the Http silverlight components use the browser's networking infrastructure to request the resources in the web servers (you can bypass it making the resource that you want to refresh periodically not to be stored in the cache - no-cache value -).
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
die iss zwar irgendwie Dirty ...
OpenReadAsync(new Uri(uri.AbsoluteUri + "?" + Guid.NewGuid().ToString())"
So unsauber ist das gar nicht.
Zum Beispiel schickt jQuery bei jedem asynchronen Request auf gleiche Weise eine einmalige ID mit, um das Cachen aktiv zu verhindern.
Ist ja nicht so, dass nur der Client cached, sondern auch der Server.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
ich hab versucht mit
actWebClient.Headers[HttpRequestHeader.IfModifiedSince] = "Sat, 19 Jul 2008 19:43:31 GMT";
aber irgendwie klappt diss nich....
und für diss "Cache-Control" hab ich auch kein Beispiel gefunden irgendwie ...
mit
actWebClient.Headers.Add("Cache-Control", "no-cache");
funktioniert wieder nich kommt nen Compilerfehler X(
Howard
Hallo,
Ein Add scheint es bei diesen Headern in Silverlight nicht zu geben.
Du kannst es mal so versuchen (ungetestet):
actWebClient.Headers[HttpRequestHeader.CacheControl] = "no-cache";
Gruß, MarsStein
Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca
Ich bin auf das selbe Problem gestoßen und habe alle Vorschläge ausprobiert,
das einzigste was geholfen hat ist die Guid am ende der Uri anzuhängen.
WebClient client = new WebClient();
Uri uri = new Uri("http://www.xxx.de");
client.DownloadStringAsync(new Uri(uri.AbsoluteUri + "&" + Guid.NewGuid().ToString()));
Habt ihr auch mal Gewusst wie: Angeben der HTTP-Behandlung durch den Browser oder Client ausprobiert?
Okay also ich hab das mal ausprobiert mit dem
RegisterPrefix
Bei mir liefert das Teil nur "false" zurück... also bringts das auch nich..
Aber mit der GUID gehts ja erstmal... kann auch gern nochwas ausprobieren wenn wer noch Vorschläge hat. 😁
Howard