2014-09-19 2 views
0

У меня 2 методы с одинаковой функциональностью:InMemoryRandomAccessStream неправильное поведение

private static async Task<IRandomAccessStream> _DownloadImage(string url) 
{ 
    HttpClient http = new HttpClient(); 
    var httpStream = await http.GetStreamAsync(url); 
    var memStream = new MemoryStream(); 
    await httpStream.CopyToAsync(memStream); 
    memStream.Seek(0, SeekOrigin.Begin); 
    return memStream.AsRandomAccessStream(); 
} 

и

private static async Task<IRandomAccessStream> _DownloadImage2(string url) 
{ 
    HttpClient http = new HttpClient(); 
    var httpStream = await http.GetStreamAsync(url); 
    var stream = new InMemoryRandomAccessStream(); 
    await httpStream.CopyToAsync(stream.AsStreamForWrite()); 
    stream.Seek(0); 
    return stream; 
} 

Проблема заключается в том, что для некоторых URL-адресов второй вариант дает нулевую длину stream. Это ошибка, или я чего-то не хватает? URL-адрес, для которого первая версия дает нормальный поток с изображением в то время как второй один пуст: http://icdn.lenta.ru/images/2014/09/17/10/20140917102331786/pic_ffa73ea27023b3e69b6cef4d068c0499.jpg

UPD:

Я обнаружил, что файлы, которые имеют размер ниже 16384 находятся в опасности. Я нашел это значение 16384 в документации AsStreamForWrite. @ Kiewic, также предложил обходное решение. Тем не менее я хотел бы знать, почему это не работает так, как есть.

UPD2: Создал bug report в Connect.

+0

Язык проекции для AsStreamForWrite() довольно некрасиво. Потоки WinRT не очень подходят для потоков .NET, поэтому для описания различий требуется большое количество кода. Множество особых случаев для работы с различными типами потоков, есть также код, который скрывает различия в предыдущих выпусках телефонов. Слишком много движущихся частей, ошибка является сильной возможностью. Вы не должны писать код, как это, в первую очередь, использование BitmapSource.SetSourceAsync() очень важно, чтобы не пережевывать много памяти. Лучше всего придерживаться кода, который работает :) –

+0

@HansPassant, я не могу создать BitmapImage в потоке, отличном от UI. – ixSci

+0

Просто верьте: вам не нужен ответ. Просто сделайте все возможное, чтобы избежать использования всех этих помощников для преобразования типов исполняемых файлов Windows в классы .NET. Если вы хотите знать, почему, просто прочитайте [этот поток] (http://social.msdn.microsoft.com/Forums/windowsapps/en-US/37ac0ed7-1884-4251-9914-07fae6467b98/mediastreamsource-not-working- правильно-в-windows-phone-81), начиная с конца. Вы избежите целого ряда проблем, включая случайные OutOfMemoryExceptions, если вы просто откажетесь от преобразования Windows Runtime в .NET. – Alovchin

ответ

1

Это работает, когда вы держите Stream в переменной, попробуйте:

// using System.Net.Http; 

private static async Task<IRandomAccessStream> _DownloadImage2(string url) 
{ 
    HttpClient http = new HttpClient(); 
    var httpStream = await http.GetStreamAsync(url); 
    var stream = new InMemoryRandomAccessStream(); 

    Stream streamForWrite = stream.AsStreamForWrite(); 
    await httpStream.CopyToAsync(streamForWrite); 

    stream.Seek(0); 
    Debug.WriteLine("Length: " + streamForWrite.Length); 
    Debug.WriteLine("Size: " + stream.Size); 

    return stream; 
} 
+0

Это действительно помогает. Но он не отвечает, почему базовая версия не работает. Пожалуйста, посмотрите обновленный пост – ixSci

Смежные вопросы