Возврат ImageSource из задачи - возможно ли это?

Кажется, я хожу по кругу с этой проблемой, которая у меня есть. Старый код, который я использовал, выглядит следующим образом:

private ImageSource LoadImg(string url)
    {
        WebClient MyWebClient = new WebClient();
        byte[] BytesFile = MyWebClient.DownloadData(url);
        Stream m2 = new MemoryStream(BytesFile);
        return ImageSource.FromStream(() => m2);

    }

И я мог бы очень легко использовать это, просто позвонив:

mainimg.Source = LoadImg(url);

Теперь я хочу преобразовать это в асинхронный режим и использовать httpClient, так как поддержка WebClient прекращается? Итак, я попытался сделать это

private async Task<ImageSource> LoadImg2Async(url)
    {
        
        System.Diagnostics.Debug.WriteLine("Firing LoadImg2");
        var httpResult = await Client.GetAsync(url);
        using var resultStream = await httpResult.Content.ReadAsStreamAsync();
        //using var fileStream = File.Create(@"c:\dev\yaythisworks.png");
        //resultStream.CopyTo(fileStream);

        return ImageSource.FromStream(() => resultStream);

    }

Кажется, есть смысл, по крайней мере, немного. Но тогда как я могу использовать этот возврат от задачи? Я пытался:

mainimg.Source = LoadImg2Async(url).Result;

но я не могу заставить его работать

У кого-нибудь есть идеи? На этот раз я честно пытался найти ответы в Google, не могу найти ответов о том, как вернуться из задач.

Большое спасибо

Эндрю

при вызове метода async используйте await. Не используйте Result. И вы можете загрузить Image прямо из URL-адреса, не выполняя всю эту дополнительную работу.

Jason 04.11.2022 17:04

Извините, я знаю, что могу загрузить напрямую. Я подстроил это, так как выполняю дополнительную работу по преобразованию PDF в изображение. Итак, я сбил это, чтобы попытаться выяснить, в чем проблема. Как я могу вернуть ImageSource из задачи? Когда я делаю var s = await LoadImg2Async(url); приложение просто зависает и ничего не делает

Andrew Taylor 04.11.2022 17:13

@ Джейсон Моя ошибка, когда я использую mainimg.Source = await LoadImg2Async(), он не зависает, как я сказал. Он завершает задачу, но источник изображения не обновляется. так что я все еще делаю что-то не так.

Andrew Taylor 04.11.2022 17:18

вы пробовали писать в файл и использовать ImageSource.FromFile?

Jason 04.11.2022 17:30

спасибо, что вернулись ко мне. Я успешно записал в файл, но в идеале я бы предпочел этого не делать. Я пытаюсь просмотреть список путей к pdf-файлам, отобразить каждый из них в виде эскиза и отобразить его в списке. Если это вообще возможно, я бы хотел сохранить его в потоке, но я не могу понять, почему это не работает. Я пытался вернуть поток, а затем преобразовать его в источник изображения позже, но у меня такая же проблема.

Andrew Taylor 04.11.2022 17:33

не уверен, что ReadAsStreamAsync требует, чтобы вы сбрасывали поток на начало - вы можете попробовать это

Jason 04.11.2022 17:38

Я попытался добавить resultstream.position = 0. Но у меня все та же проблема. Любые другие идеи?

Andrew Taylor 04.11.2022 18:24

см. ответ Стива - я полностью пропустил это

Jason 04.11.2022 19:24

@Jason - на самом деле это новый синтаксис С#. Локальная переменная, которая остается активной до конца своей области. См. ссылку в комментарии Габриэля Люси к моему ответу.

ToolmakerSteve 05.11.2022 01:08

ВОЗМОЖНО ВАЖНО: я видел предыдущие вопросы StackOverflow, в которых у людей возникали проблемы с использованием потока из MediaPicker. Найдите эти вопросы и ответы для Maui или Xamarin и посмотрите, нашел ли кто-нибудь решение (кроме сохранения в виде файла). Возможно, поток из httpResult имеет аналогичную проблему.

ToolmakerSteve 05.11.2022 01:15

Спасибо за вашу помощь. Я просто ожидал, что меня снова научат пользоваться Google: D. Мне никогда не удавалось заставить это работать, возвращая поток, я подозреваю, что ToolmakerSteve прав, и есть проблема. Мне удалось заставить его работать, возвращая массив байтов byte[] bytearray = await httpResult.Content.ReadAsByteArrayAsync(); return bytearray;, но для его использования это кажется очень неуклюжим. Мне пришлось создать еще один массив байтов, используя byte[] myarray = await LoadImg2Async(), затем настроить новый поток памяти, используя его, а затем установить поток памяти в качестве источника изображения....

Andrew Taylor 07.11.2022 09:32

@AndrewTaylor - вы можете опубликовать свое решение как «Ваш ответ» ниже. Это облегчило бы поиск будущим читателям (любые позволяют лучше форматировать код, чем в комментарии).

ToolmakerSteve 07.11.2022 23:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
12
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Спасибо всем за помощь, вы помогли мне встать на правильный путь!

Похоже, что невозможно вернуть поток из httpClient, я не знаю, почему. Когда я возился, похоже, что поток может быть пуст?! В любом случае, единственный способ, который я нашел, - это вернуть байты.

Мне пришлось изменить тип возврата Task на byte, а затем вернуть ms.ToArray();

private async Task<byte[]> LoadImg2Async(string pathtopdf)
    {   System.Diagnostics.Debug.WriteLine(pathtopdf);
        string pdfpathcorr = pathtopdf.Replace(@"Y:\", roothttpaddy);
        string url = pdfpathcorr.Replace(@"\", "/");
        System.Diagnostics.Debug.WriteLine("Corrected URL STRING = " + url);
                       
        var httpResult = await Client.GetAsync(url);
        byte[] bytearray = await httpResult.Content.ReadAsByteArrayAsync();

        MemoryStream iStream = new MemoryStream(bytearray);
        PdfFixedDocument document = new PdfFixedDocument(iStream);
        PdfRendererSettings settings = new PdfRendererSettings();
        settings.DpiX = 10;
        settings.DpiY = 10;
        MemoryStream ms = new MemoryStream();
        PdfPageRenderer renderer = new PdfPageRenderer(document.Pages[0]);
        renderer.ConvertPageToImage(ms, PdfPageImageFormat.Png, settings);
       

        //FileStream stm = File.OpenWrite(@"c:\dev\pdf " + fileid.ToString() + ".png");
        //renderer.ConvertPageToImage(stm, PdfPageImageFormat.Png, settings);
        ms.Position = 0;
       

 return ms.ToArray();
 
    }

Затем, чтобы потреблять его, мне нужно

byte[] bytearray = await LoadImg2Async(item.PDFPath);

MemoryStream stream = new MemoryStream(bytearray);

item.pdfpathconvert = ImageSource.FromStream(() => stream);

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

Любые советы или предложения?

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

Спасибо

Эндрю

Другие вопросы по теме