Кажется, я хожу по кругу с этой проблемой, которая у меня есть. Старый код, который я использовал, выглядит следующим образом:
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, не могу найти ответов о том, как вернуться из задач.
Большое спасибо
Эндрю
Извините, я знаю, что могу загрузить напрямую. Я подстроил это, так как выполняю дополнительную работу по преобразованию PDF в изображение. Итак, я сбил это, чтобы попытаться выяснить, в чем проблема. Как я могу вернуть ImageSource из задачи? Когда я делаю var s = await LoadImg2Async(url); приложение просто зависает и ничего не делает
@ Джейсон Моя ошибка, когда я использую mainimg.Source = await LoadImg2Async(), он не зависает, как я сказал. Он завершает задачу, но источник изображения не обновляется. так что я все еще делаю что-то не так.
вы пробовали писать в файл и использовать ImageSource.FromFile?
спасибо, что вернулись ко мне. Я успешно записал в файл, но в идеале я бы предпочел этого не делать. Я пытаюсь просмотреть список путей к pdf-файлам, отобразить каждый из них в виде эскиза и отобразить его в списке. Если это вообще возможно, я бы хотел сохранить его в потоке, но я не могу понять, почему это не работает. Я пытался вернуть поток, а затем преобразовать его в источник изображения позже, но у меня такая же проблема.
не уверен, что ReadAsStreamAsync требует, чтобы вы сбрасывали поток на начало - вы можете попробовать это
Я попытался добавить resultstream.position = 0. Но у меня все та же проблема. Любые другие идеи?
см. ответ Стива - я полностью пропустил это
@Jason - на самом деле это новый синтаксис С#. Локальная переменная, которая остается активной до конца своей области. См. ссылку в комментарии Габриэля Люси к моему ответу.
ВОЗМОЖНО ВАЖНО: я видел предыдущие вопросы StackOverflow, в которых у людей возникали проблемы с использованием потока из MediaPicker. Найдите эти вопросы и ответы для Maui или Xamarin и посмотрите, нашел ли кто-нибудь решение (кроме сохранения в виде файла). Возможно, поток из httpResult имеет аналогичную проблему.
Спасибо за вашу помощь. Я просто ожидал, что меня снова научат пользоваться Google: D. Мне никогда не удавалось заставить это работать, возвращая поток, я подозреваю, что ToolmakerSteve прав, и есть проблема. Мне удалось заставить его работать, возвращая массив байтов byte[] bytearray = await httpResult.Content.ReadAsByteArrayAsync(); return bytearray;, но для его использования это кажется очень неуклюжим. Мне пришлось создать еще один массив байтов, используя byte[] myarray = await LoadImg2Async(), затем настроить новый поток памяти, используя его, а затем установить поток памяти в качестве источника изображения....
@AndrewTaylor - вы можете опубликовать свое решение как «Ваш ответ» ниже. Это облегчило бы поиск будущим читателям (любые позволяют лучше форматировать код, чем в комментарии).





Спасибо всем за помощь, вы помогли мне встать на правильный путь!
Похоже, что невозможно вернуть поток из 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.
Любые советы или предложения?
Я знаю, что мой код может быть не самым оптимизированным, я просто пытался пройти его логически в данный момент, но любые советы будут приветствоваться.
Спасибо
Эндрю
при вызове метода
asyncиспользуйтеawait. Не используйтеResult. И вы можете загрузитьImageпрямо из URL-адреса, не выполняя всю эту дополнительную работу.