Laden...

Ich benutze WebClient.OpenReadAsync() ...aber Daten sind nicht aktuell

Erstellt von Howard vor 13 Jahren Letzter Beitrag vor 13 Jahren 7.275 Views
Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren
Ich benutze WebClient.OpenReadAsync() ...aber Daten sind nicht aktuell

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

3.170 Beiträge seit 2006
vor 13 Jahren

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

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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

3.170 Beiträge seit 2006
vor 13 Jahren

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

X
1.177 Beiträge seit 2006
vor 13 Jahren

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.

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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

795 Beiträge seit 2006
vor 13 Jahren

Versuche mal Folgendes:

myClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);

Gruß, Christian.

`There are 10 types of people in the world: Those, who think they understand the binary system Those who don't even have heard about it And those who understand "Every base is base 10"`
3.170 Beiträge seit 2006
vor 13 Jahren

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

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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 😁 👍

3.170 Beiträge seit 2006
vor 13 Jahren

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

16.806 Beiträge seit 2008
vor 13 Jahren

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.

Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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

3.170 Beiträge seit 2006
vor 13 Jahren

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

B
22 Beiträge seit 2008
vor 13 Jahren

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()));

2.891 Beiträge seit 2004
vor 13 Jahren
Howard Themenstarter:in
84 Beiträge seit 2007
vor 13 Jahren

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