Z jakiegoś powodu jest przerwa po uruchomieniu poniższego programu. Uważam, że przyczyną jest WebClient().DownloadStringTaskAsync()
.Dlaczego blokuje WebClient.DownloadStringTaskAsync()? - nowy asynchroniczny interfejs API/składnia/CTP
class Program
{
static void Main(string[] args)
{
AsyncReturnTask();
for (int i = 0; i < 15; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
public static async void AsyncReturnTask()
{
var result = await DownloadAndReturnTaskStringAsync();
Console.WriteLine(result);
}
private static async Task<string> DownloadAndReturnTaskStringAsync()
{
return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
}
}
O ile rozumiem, mój program powinien natychmiast rozpocząć liczenie od 0 do 15. czy robię coś źle?
Miałem ten sam problem z oryginalną próbką pobierania Netflix (którą otrzymałeś z CTP) - po naciśnięciu przycisku wyszukiwania interfejs użytkownika najpierw zawiesza się - i po pewnym czasie reaguje podczas ładowania kolejnych filmów. I wierzę, że to nie zamarzło w prezentacji Andersa Hejlsberga na PDC 2010.
Jeszcze jedno. Kiedy zamiast
return await new WebClient().DownloadStringTaskAsync(new Uri("http://www.weather.gov"));
używam moje własne metody:
return await ReturnOrdinaryTask();
który jest:
public static Task<string> ReturnOrdinaryTask()
{
var t = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("------------- " + i.ToString());
Thread.Sleep(100);
}
return "some text";
});
return t;
}
To działa tak jak powinno. Chodzi mi o to, że nic nie ładuje, ale zaczyna się od razu i nie blokuje głównego wątku, wykonując jego pracę.
Edit
OK, w co wierzę teraz to: funkcja WebClient.DownloadStringTaskAsync
przykręcony jest do góry. Powinien działać bez początkowego okresu blokującego, tak:
static void Main(string[] args)
{
WebClient cli = new WebClient();
Task.Factory.StartNew(() =>
{
cli.DownloadStringCompleted += (sender, e) => Console.WriteLine(e.Result);
cli.DownloadStringAsync(new Uri("http://www.weather.gov"));
});
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
Thread.Sleep(100);
}
}
tak - widzę, że działa tak, jak powiedziałeś - ale wierzę, że to jakiś błąd - chodzi o to, że operacje asynchroniczne, takie jak DownloadStringTaskAsync(), nie blokują wątku głównego/ui/wywołującego - wszystko, co wymaga czas powinien zaczynać się na innym wątku i natychmiast powrócić (w inny sposób - o co chodzi?). Tak więc pytanie brzmi: czy robię coś złego lub metoda DownloadStringTaskAsync() jest zepsuta - wiem, że jest to teraz protokół ctp/prototyp. Ale dziwne jest to, że wydawało się działać dobrze (bez wstępnego blokowania) na komputerze Hejlsberga podczas prezentacji. – agend
Czy ktoś mógłby sprawdzić ten kod na swoim komputerze i potwierdzić początkowe zachowanie blokujące? TIA Arek – agend
@agend, uruchomiłem to na mojej własnej maszynie i widzę początkowe zachowanie blokujące. – driis