Вы отметили async-await
и пишете асинхронно в своем заголовке. Однако весь ваш код выполняется в основном потоке, а не асинхронно.
Вместо загрузки данных в конструктор ViewModel. Я настоятельно рекомендую вам использовать событие жизненного цикла, такое как OnAppearing
на вашем Page
и запускать ICommand
для асинхронной загрузки ваших данных.
Кроме того, я бы переключился на использование HttpClient
и его приятной асинхронности c API. Так что-то вроде:
public class GalleryService
{
private HttpClient _httpClient;
public GalleryService()
{
_httpClient = new HttpClient();
}
public async Task<IEnumerable<picdata>> GetImageList(string pCode, string gCode, string gUrl)
{
var response = await _httpClient.GetAsync(gUrl).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var deserialized = JsonConvert.DeserializeObject<JsonTxt>(json);
var images = new List<picdata>();
foreach(var img in deserialized.Files)
{
images.Add(new picdata()
{
ImageName = img.file,
BaseUrl = deserialized.Settings.Path.ToString(),
ThumbUrl = deserialized.Settings.Path.ToString() + "/thumbs" + img.file
});
}
return images;
}
return new picdata[0]; // return empty set
}
}
и ViewModel:
public class GalleryViewModel
{
private GalleryService _galleryService;
public ObservableCollection<picdata> Galleries { get; } = new ObservableCollection<picdata>();
public ICommand GetImagesCommand { get; }
public GalleryViewModel(string pCode, string gCode, string gUrl)
{
_galleryService = new GalleryService();
GetImagesCommand = new Command(async () => DoGetImagesCommand(pCode, gCode, gUrl));
}
private async Task DoGetImagesCommand(string pCode, string gCode, string gUrl)
{
var images = await _galleryService.GetImageList(pCode, gCode, gUrl);
foreach(var image in images)
Galleries.Add(image);
}
}
Затем в вашем OnAppearing()
переопределении на вашей странице вы можете вызвать что-то вроде: (BindingContext as GalleryViewModel).GetImagesCommand.Execute(null);
Убедитесь, что вы установили BindingContext
, прежде чем пытаться вызвать команду. Это можно сделать в конструкторе страницы с помощью:
BindingContext = new GalleryViewModel();
Таким образом, вы не блокируете весь свой пользовательский интерфейс, пока не закончится загрузка изображений. В качестве альтернативы вы можете запустить задачу с помощью Task.Run
в конструкторе ViewModel. Однако тогда вам придется маршалировать совокупность ObservableCollection в потоке пользовательского интерфейса.