асинхронная задача Android Xamarin - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь загрузить изображение из URL, чтобы позже включить его в запись списка. Проблема в том, что он не ожидает завершения асинхронной задачи. Он выполняет добавление, но изображение является нулевым, поскольку асинхронный метод не завершен.

Как заставить его ждать, пока изображение загрузится, и затем добавить запись в список?

private JavaList<Spacecraft> GetSpacecrafts()
{
    spacecrafts = new JavaList<Spacecraft>();
    Spacecraft s;
    foreach (DataRow row in tbs.Rows)
    {
        var t = Task.Run(() => CallMethod(row["nueve_seis"].ToString()));
        t.Wait();
        s = new Spacecraft(row["nombre"].ToString(),,row["uno_cutrocuatro"].ToString(), row["nombre"].ToString(), row["desc"].ToString(), row["urllocal"].ToString(), row["urlPublica"].ToString(), row["cuatro_ocho"].ToString(), row["siete_dos"].ToString(), row["nueve_seis"].ToString(), row["uno_cutrocuatro"].ToString(), row["uno_nuevedos"].ToString(), imageBitmap);
        spacecrafts.Add(s);
    }
    async void CallMethod(string nameimage)
    {
        await EjecutaTareaAsync(nameimage);
    }
    async Task EjecutaTareaAsync(string pathimg)
    {
        await Task.Run(() =>
        {
            imageBitmap = null;
            imageBitmap = GetImageBitmapFromUrl(pathimg);
        });
    }
    return spacecrafts;
}

private Bitmap GetImageBitmapFromUrl(string url)
{
    using (var webClient = new WebClient())
    {
        var imageBytes = webClient.DownloadData(url);
        if (imageBytes != null && imageBytes.Length > 0) return BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
    }
    return null;
}

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Используйте этот код, он может вам помочь

private async Task<Bitmap> GetImageBitmapFromUrl(string url)
{
    Uri param_url = new Uri(url);
    var webClient = new WebClient();
    var imageBytes = await webClient.DownloadDataTaskAsync(param_url);
    if (imageBytes != null && imageBytes.Length > 0) return BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
    return null;
}

void EjecutaTareaAsync(string pathimg)
{
    Task.Run(async() =>{ imageBitmap =await GetImageBitmapFromUrl(pathimg); }).Wait(); //this will wait until task completed
}
0 голосов
/ 15 сентября 2018

Хорошо, давайте начнем сверху.Вы хотите, чтобы он ожидал в foreach, когда вы вызываете CallMethod (...).Итак, давайте сделаем метод асинхронным методом.После этого добавьте ожидание перед вызовом метода.

Это было избыточно при настройке асинхронных / ожидающих вызовов.поэтому я удалил один из методов и немного консолидировал.

https://blog.xamarin.com/getting-started-with-async-await/ довольно хорошее чтение, и они говорят о том, как использовать async / await.это может быть полезно.

private async JavaList<Spacecraft> GetSpacecrafts()
{
    spacecrafts = new JavaList<Spacecraft>();
    Spacecraft s;
    foreach (DataRow row in tbs.Rows)
    {
        var t = await CallMethod(row["nueve_seis"].ToString());
        s = new Spacecraft(row["nombre"].ToString(),,row["uno_cutrocuatro"].ToString(), row["nombre"].ToString(), row["desc"].ToString(), row["urllocal"].ToString(), row["urlPublica"].ToString(), row["cuatro_ocho"].ToString(), row["siete_dos"].ToString(), row["nueve_seis"].ToString(), row["uno_cutrocuatro"].ToString(), row["uno_nuevedos"].ToString(), imageBitmap);
        spacecrafts.Add(s);
    }
    return spacecrafts;
}

async Task CallMethod(string nameimage)
{
    return await Task.Run(() =>
    {
        imageBitmap = null;
        imageBitmap = GetImageBitmapFromUrl(pathimg);
    });
}

private Bitmap GetImageBitmapFromUrl(string url)
{
    using (var webClient = new WebClient())
    {
        var imageBytes = webClient.DownloadData(url);
        if (imageBytes != null && imageBytes.Length > 0) return BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
    }
    return null;
}
...