Просмотр состояния в обработчике .ashx? - PullRequest
4 голосов
/ 27 апреля 2010

У меня есть обработчик (например, list.ashx), у которого есть метод, который извлекает большой набор данных, а затем захватывает только записи, которые будут показаны на любой данной «странице» данных. Мы разрешаем пользователям выполнять сортировку по этим результатам. Таким образом, при каждом запуске страницы я буду извлекать набор данных, который я только что получил несколько секунд / минут назад, но переупорядочивать их или показывать следующую страницу данных и т. Д.

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

Итак, каков общий способ хранения состояния просмотра, связанного с данной страницей текущего пользователя, при использовании обработчика? Есть ли способ взять набор данных, каким-то образом его кодировать и отправить его обратно пользователю, а затем при следующем вызове передать его обратно и затем повторно сформировать набор данных из этих битов?

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

Кто-нибудь имеет опыт работы с подобной ситуацией, и вы можете дать мне какой-нибудь совет?

Ответы [ 3 ]

3 голосов
/ 27 апреля 2010

В этой ситуации я бы использовал кеш с некоторым типом пользователя и информацией запроса в качестве ключа. Причина в том, что вы говорите, что это большой набор данных. Прямо там есть то, что вы не хотите постоянно толкать вверх и вниз по трубе. Помните, что ваш сервер все еще должен получать данные, если он находится в ViewState, и обрабатывать их. Я хотел бы сделать что-то вроде этого, что бы кэшировать его для конкретного пользователя и иметь короткий срок действия:

public DataSet GetSomeData(string user, string query, string sort)
{
    // You could make the key just based on the query params but figured
    // you would want the user in there as well.
    // You could user just the user if you want to limit it to one cached item
    // per user too.
    string key = string.Format("{0}:{1}", user, query);

    DataSet ds = HttpContext.Current.Cache[key] as DataSet;
    if (ds == null)
    {
        // Need to reload or get the data
        ds = LoadMyData(query);

        // Now store it and make the expiry short so it doesn't bog up your server
        // needlessly... worst case you have to retrieve it again because the data
        // has expired.
        HttpContext.Current.Cache.Insert(key, ds, null,
            DateTime.UtcNow.AddMinutes(yourTimeout), 
            System.Web.Caching.Cache.NoSlidingExpiration);
    }

    // Perform the sort or leave as default sorting and return
    return (string.IsNullOrEmpty(sort) ? ds : sortSortMyDataSet(ds, sort));
}

Когда вы говорите «тысячи пользователей», означает ли это одновременных пользователей? Если время истечения было 1 минута, сколько одновременных пользователей совершит этот вызов в минуту и ​​потребует сортировки. Я думаю, что выгрузка данных в нечто похожее на ViewState - это просто обмен некоторой кэш-памяти на пропускную способность и загрузку больших запросов вперед и назад. Чем меньше вы будете передавать туда и обратно, тем лучше, на мой взгляд.

2 голосов
/ 27 апреля 2010

Почему бы вам не внедрить кэширование на стороне сервера?

A Я понимаю, что вы извлекаете большой объем данных, а затем возвращаете только необходимые записи из этих данных разным клиентам. Таким образом, вы можете использовать HttpContext.Current.Cache свойство для этого.

например. можно использовать свойство, которое инкапсулирует логику извлечения данных (получает из исходного хранилища данных с первым запросом, затем помещает в кеш и получает из кеша при каждом следующем запросе). В этом случае все необходимые манипуляции с данными (подкачка страниц и т. Д.) Могут выполняться намного быстрее, чем извлечение большого объема данных с каждым запросом.

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

1 голос
/ 27 апреля 2010

Лучшее, что вы можете сделать, это «вырастить свой», включив сериализованный набор данных в тело запроса к обработчику ASHX. Затем ваш обработчик проверяет, действительно ли запрос имеет тело, проверяя Request.ContentLength, а затем считывая из Request.InputStream, и выполняет ли он сериализацию этого тела обратно в набор данных вместо чтения из вашей базы данных.

...