асинхронный стримминг при отдаче данных
От: MadHuman Россия  
Дата: 22.06.18 14:41
Оценка:
Всем привет!

Нужно организовать отдачу клиенту (браузеру) потенциально большого объёма данных, генерящихся на лету (например это могут быть данные в csv формате).
Сами данные формируются на лету и допустим есть IEnumerable<string> при переборе которого они и формируются.
Как лучше это сделать правильно?
По умолчанию, если писать Response.Write — то все данные будут идти в буфер и при большом их количестве мы либо влетим в OutOfMemoryException либо выжрем слишком много памяти — вообщем невариант.
Если в asp.net отключить беферизацию вывода, то при записе в Response данные сразу будут посылаться в сеть и мелкими кусочками? имеет ли смысл организовывать свою буферизацию (чтоб при достижении какого-то объема данных — они посылались клиенту)?
И как можно делать асинхронно? так как генерация и посылка данных могут занять достаточно много времени, то поток, обрабатывающий реквест, большую часть времени будет ждать сеть...

Кто решал подобную задачу, или имеет представление как можно, поделитесь знанием...
Re: асинхронный стримминг при отдаче данных
От: Sharov Россия  
Дата: 22.06.18 15:19
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Всем привет!


MH>Нужно организовать отдачу клиенту (браузеру) потенциально большого объёма данных, генерящихся на лету (например это могут быть данные в csv формате).

MH>Сами данные формируются на лету и допустим есть IEnumerable<string> при переборе которого они и формируются.
MH>Как лучше это сделать правильно?
MH>По умолчанию, если писать Response.Write — то все данные будут идти в буфер и при большом их количестве мы либо влетим в OutOfMemoryException либо выжрем слишком много памяти — вообщем невариант.
MH>Если в asp.net отключить беферизацию вывода, то при записе в Response данные сразу будут посылаться в сеть и мелкими кусочками? имеет ли смысл организовывать свою буферизацию (чтоб при достижении какого-то объема данных — они посылались клиенту)?
MH>И как можно делать асинхронно? так как генерация и посылка данных могут занять достаточно много времени, то поток, обрабатывающий реквест, большую часть времени будет ждать сеть...

MH>Кто решал подобную задачу, или имеет представление как можно, поделитесь знанием...


Читайте из файла. MemoryStream тут вообще не нужен.
Кодом людям нужно помогать!
Re: асинхронный стримминг при отдаче данных
От: Qulac Россия  
Дата: 22.06.18 16:20
Оценка:
Здравствуйте, MadHuman, Вы писали:

MH>Всем привет!


MH>Нужно организовать отдачу клиенту (браузеру) потенциально большого объёма данных, генерящихся на лету (например это могут быть данные в csv формате).

MH>Сами данные формируются на лету и допустим есть IEnumerable<string> при переборе которого они и формируются.
MH>Как лучше это сделать правильно?
MH>По умолчанию, если писать Response.Write — то все данные будут идти в буфер и при большом их количестве мы либо влетим в OutOfMemoryException либо выжрем слишком много памяти — вообщем невариант.
MH>Если в asp.net отключить беферизацию вывода, то при записе в Response данные сразу будут посылаться в сеть и мелкими кусочками? имеет ли смысл организовывать свою буферизацию (чтоб при достижении какого-то объема данных — они посылались клиенту)?
MH>И как можно делать асинхронно? так как генерация и посылка данных могут занять достаточно много времени, то поток, обрабатывающий реквест, большую часть времени будет ждать сеть...

MH>Кто решал подобную задачу, или имеет представление как можно, поделитесь знанием...


Можно создать свой класс Stream, который и будет по необходимости генерить данные "на лету" и запихнуть его в класс FileResult.
Программа – это мысли спрессованные в код
Re[2]: асинхронный стримминг при отдаче данных
От: MadHuman Россия  
Дата: 22.06.18 16:26
Оценка:
Здравствуйте, Sharov, Вы писали:


S>Читайте из файла. MemoryStream тут вообще не нужен.

дак нет файла.. данные на лету формируются..
Re[3]: асинхронный стримминг при отдаче данных
От: Sharov Россия  
Дата: 22.06.18 16:29
Оценка:
Здравствуйте, MadHuman, Вы писали:

S>>Читайте из файла. MemoryStream тут вообще не нужен.

MH>дак нет файла.. данные на лету формируются..

Ну так попробуйте писать в файл, тем более если может быть много данных, а потом из файла гоните в сеть.
Кодом людям нужно помогать!
Re[4]: асинхронный стримминг при отдаче данных
От: MadHuman Россия  
Дата: 22.06.18 16:32
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, MadHuman, Вы писали:


S>>>Читайте из файла. MemoryStream тут вообще не нужен.

MH>>дак нет файла.. данные на лету формируются..

S>Ну так попробуйте писать в файл, тем более если может быть много данных, а потом из файла гоните в сеть.

дак тогда пока всё не запишется файл гнать не получится, будет и задержка большая (пока всё не сформируется) да и размер файла может оказаться значительным.
Re[5]: асинхронный стримминг при отдаче данных
От: Sharov Россия  
Дата: 22.06.18 16:56
Оценка:
Здравствуйте, MadHuman, Вы писали:

S>>Ну так попробуйте писать в файл, тем более если может быть много данных, а потом из файла гоните в сеть.

MH>дак тогда пока всё не запишется файл гнать не получится, будет и задержка большая (пока всё не сформируется) да и размер файла может оказаться значительным.

Зачем все? Записали 1Мб в файл, просигналили о готовке данных отправителю, он отправил 1Мб и будет ждать сл. сигнала. Как-то так.
Кодом людям нужно помогать!
Re: асинхронный стримминг при отдаче данных
От: takTak  
Дата: 22.06.18 18:19
Оценка: 118 (2)
PushStreamContent:

[HttpGet]
        public HttpResponseMessage Export(int id)
        {
            var response = Request.CreateResponse();
            response.Content = new PushStreamContent(
            async (outputStream, httpContent, transportContext) =>
            {
                try
                {
                    for (int page = 0; page < 10; page++)
                    {
                        string data = await GetData(id, page);
                        var buffer = Encoding.UTF8.GetBytes(data);
                        await outputStream.WriteAsync(buffer, 0, buffer.Length);
                    }
                }
                catch (HttpException ex)
                {
                    return;
                }
                finally
                {
                    outputStream.Close();
                }
            }, new MediaTypeHeaderValue("application/octet-stream"));
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = "myfile.csv"
            };
            return response;
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.