Użycie DownloadStringAsync w klasie.

Użycie DownloadStringAsync w klasie.
MC
  • Rejestracja:prawie 21 lat
  • Ostatnio:prawie 10 lat
  • Postów:15
0

Cześć.
Borykam sie z pewnym problemem, którego rozwiązania nie mogę znaleźć w google więc postanowiłem zapytać Was.
Otóż mam pewną klasę, załóżmy "obraz". Ma ona publiczną zmienną "url" oraz metodę "download".
Teraz, po wywołaniu metody "download", za pomocą DownloadStringAsync chciałbym pobrać źródło strony podanej w zmiennej "url", trochę je przetworzyć i zwrócić jako wynik tej metody.
Nie mam pojęcia jak się za to zabrać więc pytam Was. Docenię każdą pomoc.

Pozdrawiam.

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 15 godzin
1

za http://www.albahari.com/nutshell/cs4ch21.aspx:

Kopiuj
var wc = new WebClient();
wc.DownloadStringCompleted += (sender, args) =>
{
  if (args.Cancelled)
    Console.WriteLine ("Canceled");
  else if (args.Error != null)
    Console.WriteLine ("Exception: " + args.Error.Message);
  else
  {
    Console.WriteLine (args.Result.Length + " chars were downloaded");
    // We could update the UI from here...
  }
};
wc.DownloadStringAsync (new Uri ("http://www.linqpad.net"));  // Start it

a w Visualu 2012 będzie można tak:

Kopiuj
var wc = new WebClient();
string Result = await wc.DownloadStringTaskAsync("http://cośtam.com");
// ...
edytowany 1x, ostatnio: Azarien
Ktos
O ile metoda używająca await będzie miała adnotację async oraz będzie zwracać Task<cośtam> albo void.
MC
  • Rejestracja:prawie 21 lat
  • Ostatnio:prawie 10 lat
  • Postów:15
0

Do tego doszedłem nawet wcześniej sam. Jednak pojawił się problem z którym nie potrafiłem sobie poradzić.

Mój kod metody wygląda tak:

Kopiuj
       public string getLinks()
        {
            WebRequest.DefaultWebProxy = null;
            var download = new WebClient();
            Uri uri = new Uri(url);
            download.Encoding = Encoding.UTF8;

            download.DownloadStringCompleted += (sender, args) =>
            {
                if (args.Cancelled)
                    zrodlo = "Canceled";
                else if (args.Error != null)
                    zrodlo = "Blad: " + args.Error.Message;
                else
                {
                    zrodlo = args.Result;
                }
            };
            download.DownloadStringAsync(uri);
            return zrodlo;
        }

Zmienna "zrodlo" jest zmienną publiczną klasy "obraz".
No i teraz odwołując się do klasy "obraz" kodem:

Kopiuj
obraz obrazek = new obraz();
obrazek.url = "http://www.adres.pl";
string zrodlo = obrazek.getLinks();

zmienna zrodlo jest pusta. Próbowałem wrzucić returna w metodzie getLinks po drugim else (zamiast zrodlo = args.Result dać return args.Result) ale wtedy pojawiają się błędy:

Error 1 Since 'System.Net.DownloadStringCompletedEventHandler' returns void, a return keyword must not be followed by an object expression

oraz

Error 2 Cannot convert lambda expression to delegate type 'System.Net.DownloadStringCompletedEventHandler' because some of the return types in the block are not implicitly convertible to the delegate return type

Jak sobie z tym poradzić? Jak sprawić, żeby metoda zwróciła wynik dopiero po pobraniu źródła? Z góry dziękuję za pomoc.

Pozdrawiam

edytowany 1x, ostatnio: MiChUUUU
Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 15 godzin
1

Nie rozumiesz pojęcia asynchroniczności. Wywołanie DownloadStringAsync nie oznacza, że w nastepnej linijce mamy pobranego stringa. Tak naprawdę, to funkcja ta kończy działanie (prawie) natychmiast, a pobieranie kontynuuje się w tle.

Taki kod:

Kopiuj
download.DownloadStringCompleted += (sender, args) =>
            {
                if (args.Cancelled)
                    zrodlo = "Canceled";
                else if (args.Error != null)
                    zrodlo = "Blad: " + args.Error.Message;
                else
                {
                    zrodlo = args.Result;
                }
            };
download.DownloadStringAsync(uri);
  1. rozpoczyna pobieranie stringa z adresu w uri
  2. kończy działanie natychmiast, a pobieranie dzieje się w tle
  3. gdy pobieranie się zakończy, wykonuje się dopiero to co wrzucono w DownloadStringCompleted.

Lepiej zrób najpierw działający przykład ze zwykłym DownloadString().

zatem jak robisz:

Kopiuj
            download.DownloadStringAsync(uri);
            return zrodlo;

to jest jasne, że zmienna zrodlo jest (jeszcze) pusta. linijka z "zrodlo = args.Result;" wykona się dopiero po ściągnięciu pliku.

edytowany 3x, ostatnio: Azarien

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.