2009-05-20 2 views
1

1) ClientApp делает вызов асинхронной ASP.Net 2.0 WebService 2) Web-служба требует SQL Server 2005 хранимая процедура 3) хранимая процедура возвращает выходные данные, 150MB таблицыWeb Service Из Exception памяти при заполнении набора данных ADO.NET

Недостаточно памяти Исключение выбрано DataAdapter.Fill (...) при попытке выделить больше памяти для новых строк.

Пул приложений IIS не имеет ограничений на максимальную память.

Существуют ли максимальные ограничения использования памяти, установленные где-то еще на уровне IIS? Делает ли таблица бит 150 МБ намного больше места при чтении в память в виде DataSet? Есть ли сценарий (возможно, с WCF), где результат процедуры никогда не должен находиться в памяти веб-сервера, но будет передаваться непосредственно клиенту?

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

Любые предложения, рекомендации или советы будут оценены по достоинству.

+0

Пара вопросов. 1) находится ли это на 32-разрядной версии Windows Server? 2) насколько велик рабочий процесс Application Pool при его сбое? – Jeff

ответ

5

Да, использование DataSets использует намного больше памяти, чем фактические данные. Сколько сложно определить количественно, но вопрос this на StackOverflow предлагает более чем в 4 раза больше исходного размера. Предположим, что это правильно. 150 МБ данных 4 = 600 МБ памяти. Когда приложение ASP.NET использует около 800 МБ ОЗУ, они начнут выдавать OutOfMemoryExceptions. Я не уверен, как этот предел совпадает с лимитом памяти пула приложений. Вы пробовали переключатель/3GB в boot.ini? (См this article инструкции)

Также обратите внимание, что если вы сериализации ваш DataSet, сериализатор может выделять огромные буферы для сериализации (до 10 раз от первоначального размера, см this article. Вы указываете, что эта проблема возникает, когда вы читаете данные, поэтому это, вероятно, не является причиной вашей ошибки (но может быть, если вы решите ошибку из памяти и попытаетесь отправить данные по проводу).

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

Другим (возможно, лучшим) решением будет использование DataReader и чтение o ne row за раз. Верните партии строк (т. Е. Используйте какой-то пейджинг для данных) и поэкспериментируйте с размером каждой партии, чтобы найти сладкое пятно между производительностью и использованием памяти. Потоковая передача WCF может сделать трюк, но вам нужно будет правильно настроить WCF, чтобы он мог возвращать такие огромные объемы данных за один вызов.

0

Наилучшие практики: a) Не возвращать так много данных и b) Использовать WCF вместо четырехлетней технологии (веб-службы ASMX).

+0

Как WCF позаботится об исключении ADO.Net DataSet.Fill()? Недостаточно памяти, прежде чем DataSet будет полностью загружен в память веб-серверов. Он даже не начинает сериализоваться для транспорта в качестве ответа веб-службы. Можно ли настроить WCF для потоковой передачи данных клиенту непосредственно из SQL без необходимости его загрузки в память в DataSet? – Tion

+2

Я знаю, что WCF может передавать поток, возвращая System.IO.Stream. Хуже того, вы можете использовать ExecuteReader.Затем создайте XmlWriter по выходному потоку, и для каждой строки, которую вы возвращаете с помощью Read, напишите один элемент XML с содержимым. Это больше кода, но он должен работать. Есть, вероятно, и лучшие способы. Вам действительно нужно вернуть все 150 МБ за один раз? –

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