Работа с System.Threading.Tasks.Task <Stream>вместо Stream - PullRequest
7 голосов
/ 06 декабря 2011

Я использовал метод, подобный приведенному ниже, в предыдущих версиях веб-API WCF:

// grab the posted stream
Stream stream = request.Content.ContentReadStream;

// write it to   
using (FileStream fileStream = File.Create(fullFileName, (int)stream.Length)) {

    byte[] bytesInStream = new byte[stream.Length];
    stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
    fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}

Но в предпросмотре 6 свойство HttpRequestMessage.Content.ContentReadStream исчезло.Я полагаю, что теперь это должно выглядеть так:

// grab the posted stream
System.Threading.Tasks.Task<Stream> stream = request.Content.ReadAsStreamAsync();

Но я не мог понять, каким должен быть остальной код внутри оператора using.Кто-нибудь может предоставить мне способ сделать это?

Ответы [ 3 ]

9 голосов
/ 06 декабря 2011

Возможно, вам придется настроить это в зависимости от того, что код происходит до / после, и нет обработки ошибок, но что-то вроде этого:

Task task = request.Content.ReadAsStreamAsync().ContinueWith(t =>
{
    var stream = t.Result;
    using (FileStream fileStream = File.Create(fullFileName, (int) stream.Length)) 
    {
        byte[] bytesInStream = new byte[stream.Length];
        stream.Read(bytesInStream, 0, (int) bytesInStream.Length);
        fileStream.Write(bytesInStream, 0, bytesInStream.Length);
    }
});

Если позже в вашем коде вам нужно убедиться,что это завершено, вы можете позвонить task.Wait(), и он будет блокироваться до тех пор, пока это не завершится (или не сгенерирует исключение).

Я настоятельно рекомендую паттернам параллельного программирования Стивена Тоуба поднятьсяускорить работу некоторых новых асинхронных шаблонов (задачи, параллелизм данных и т. д.) в .NET 4.

7 голосов
/ 06 декабря 2011

Быстрое и грязное исправление:

// grab the posted stream
Task<Stream> streamTask = request.Content.ReadAsStreamAsync();
Stream stream = streamTask.Result; //blocks until Task is completed

Имейте в виду, что тот факт, что версия синхронизации была удалена из API, говорит о том, что вы действительно должны пытаться изучить новые асинхронные парадигмы, чтобы избежать сожжения многихпотоки под высокой нагрузкой.

Вы можете, например:

streamTask.ContinueWith( _ => {
    var stream = streamTask.Result; //result already available, so no blocking
    //work with stream here
} )

или с новыми функциями асинхронного ожидания:

//async wait until task is complete
var stream = await request.Content.ReadAsStreamAsync(); 

Найдите время, чтобы изучить асинхронное / ожидание.Это очень удобно.

1 голос
/ 22 октября 2015

Вот как вы можете сделать это лучше с async и await:

    private async void WhatEverMethod()
    {
        var stream = await response.Content.ReadAsStreamAsync();

        using (FileStream fileStream = File.Create(fullFileName, (int)stream.Length))
        {
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    });
...