Что возвращает Task> и как работать с возвращаемым значением после?
Я пишу небольшое мобильное приложение. У меня есть метод, который обрабатывает данные полученные из БД(добавляет каждую запись из БД в коллекцию List<string>). В конце метода я возвращаю созданную коллекцию.
private async Task<List<string>> getAllEvent()
{
List<UserEvent> events = new List<UserEvent>();
List<string> stringsInTable = new List<string>();
string tenUrl;
string temp;
HttpResponseMessage response;
while (stringsInTable.Count < 10)
{
tenUrl = "http://ссылка на сайт/контроллер";
response = await allEvent.GetAsync(tenUrl + numberEvent);
temp = await response.Content.ReadAsStringAsync();
if(temp.Contains("Not Found"))
{
break;
}
stringsInTable.Add(temp);
numberEvent++;
}
//await DisplayAlert("Тест", stringsInTable.Count.ToString(), "Ок");
return stringsInTable;
}
После я хочу вывести в DisplayAlert со значением первого элемента из коллекции по нажатию кнопки, но следующий код не работает. Как я понял, вызов метода возвращает не List<string>, а Task<List<string>>, это верно ?
private void Button_Clicked(object sender, EventArgs e)
{
List<string> test = new List<string>();
test = getAllEvent().Result;
DisplayAlert("alert",test[0],"ok");
}
После я сделал обработчик нажатия кнопки асинхронным и переписал код следующим образом.
private async void Button_Clicked(object sender, EventArgs e)
{
List<string> test = new List<string>();
test = await getAllEvent();
await DisplayAlert("alert",test[0],"ok");
}
Теперь код работает, но я не понимаю почему. Правильно ли написан обработчик нажатия кнопки ? И где можно почитать о работе с возвращаемым значением Task<TResult> ?
Ответы (1 шт):
Я попробую ответить на Ваш вопрос максимально простыми словами. Формальный ответ о том, что такое Task - можно найти здесь, например.
Итак, сначала о том, что такое Task.
Вот есть у Вас функция. При "обычном" или "синхронном" вызове функции всё просиходит так: код "доходит до места вызова функции, потом проваливается в функцию, функция выполняется, и уже потом управление возвращается на следующую строку после вызова функции".
А теперь пускай у нас есть функция, помеченная модификатором async. При вызове такой функции "вызов" отрабатывает мгновенно. Да - да, вы не ослышались. Вы вызвали функцию? Все хорошо. Работайте дальше. Когда функция сделает свою работу - то управление вернётся на следующую за вызовом строку.
Таким образом, у нас получается такая "событийно управляемая модель": надо что то отобразить на форме, а вызов этой штуки происходит через сеть и через полмира? - ничего, мы пошлём вызов, и можно пока на форме спокойно нажимать другие кнопки, она не "зафризится". а когда результат вернётся с другой стороны земного шара - код продолжит свою работу, и нарисует Вам этот несчастный комбобокс, уже заполненный значениями.
То есть, самыми грубыми словами, Task - это "обещание сделать работу, и когда работа будет сделана - продолжить выполнять код с того же места"
А теперь - что такое Tresult. Очень просто. Вот есть у вас void-функция. Она ничего не возвращает. Если её переделывать в асинхронную - тип с void сменится на "просто Task".
А если функция возвращает какое то значение, например, string - то при переделке на асинхронную версию она будет возвращать Task - то есть, Task, у которого еще есть и результат функции, поэтому тип этого результатат входит в декларацию функции.
Надеюсь, моё объяснение будет хотя бы в какой то мере полезно.