Asp кэшируйте часто используемые данные на сервере


Содержание

MVC — Как кэшировать часто используемые и измененные User_Data (для веб-игры)

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

Некоторые из них редко меняются, но некоторые (например, опыт, навыки, уведомления или монеты) могут часто меняться.

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

Есть ли какой-нибудь известный, хороший подход? Или я должен забыть и сделать дополнительные 2-3 SQL-запроса при каждой загрузке страницы?

«Часто измененный» в значительной степени исключает кеширование. Я думаю, что существует одержимость оптимизацией, которая заставляет людей хотеть кэшировать все, но у вас есть база данных по какой-то причине, и это вполне приемлемо для запроса.

Однако вы можете использовать части кеша. Кое-что вроде Level обычно не меняется так часто, как требуется время, чтобы перейти от одного к другому. Это может быть кэшировано, и достаточно легко просто перехватить кеш, когда уровень изменится, и тогда он будет перезагружен. Другие вещи, такие как Coins у пользователя всегда должны быть точными и точными. Очевидно, вам придется сделать эти определения.

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

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

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

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

Полезные советы по оптимизации ASP-приложений

Введение

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

Публикуемый ниже материал представляет собой первый совет из целой серии советов по оптимизации приложений, использующих технологии ASP и Visual Basic Scripting Edition (VBScript). Большинство из них были многократно обсуждены и c успехом проверены на веб-сайте Microsoft Corporation и других ASP-сайтах. Авторы материала подразумевают, что вы уже знакомы с основами разработки ASP-приложений, включая VBScript и/или JScript, ASP-сессиями и др. важными объектами (Request, Response и Server).

Кэшируйте часто используемые данные на сервере

Типичная ASP-страница получает данные из базы данных и затем выводит их в формате HTML. Независимо от скорости вашей базы данных, получение данных из памяти сервера намного быстрее, чем обработка sql-запроса к конечной базе данных. Получение данных, сохраненных на локальном жестком диске, также обычно быстрее, чем получение информации из БД. Поэтому одним из основных путей увеличения скорости работы вашей ASP-страницы является кэширование часто используемой информации в памяти или на жестком диске.

Кэширование данных — это классический компромисс место или время. Если вы избрали для кэширования правильный материал, вы можете видеть внушительное повышение производительности вашего приложения. Чтобы кэширование было эффективным нужно использовать для временного хранения только те данные, которые многократно используются для вывода и каждый раз трудоемки для повторных вычислений. Кэш, полный устаревшей информации, будет пустой тратой памяти сервера.

Данные, которые не изменяются часто, являются хорошим кандидатом для кэширования, потому что вам не надо будет волноваться относительно их синхронизации через какое-то время с конечной базой данных. Выпадающие списки (сombo-box), таблицы ссылок, пункты меню, и переменные конфигурации сайта (включая имена DSN, адреса IP и URL) — первые кандидаты для хранения в кэше. Заметьте, что вы можете кэшировать представление данных много быстрее, нежели данные сами себя. Если ASP-страница изменяется не так часто и ее временный кэш будет весьма внушительным (например, полный каталог изделий фирмы), попробуйте использовать сгенерированные HTML-страницы, чем каждый раз загружать сервер генерацией ASP-страниц.

Кэшируйте часто используемые данные в объектах Application или Session

Объекты Application и Session служат для хранения данных в памяти, значения которых могут быть доступны между несколькими HTTP-запросами (в отличие от обычных переменных, чьи значения доступны только в теле одной ASP-страницы). Данные объекта Session доступны только одному пользователю (в течении его сессии), в то время как данные Application доступны всем пользователям веб-сайта. Поэтому часто перед разработчиком возникает вопрос: в каком из объектов сохранять часто используемые данные. Обычно, для инициализации переменных этих объектов используются процедуры файла Global.asa — Application_OnStart() или Session_OnStart() соответственно. Если в вашем Global.asa еще нет этих процедур, то вы можете добавить их сами или инициализировать переменные, когда это будет необходимо. Примером может быть следующая процедура, использующая Application для хранения значений многократно использующейся переменной EmploymentStatusList. Процедура проверяет существование данных в EmploymentStatusList и при необходимости расчитывает их заново:

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

Сохранить значение recordset в виде массива

Если полученный массив будет часто использоваться, тогда лучше хранить его сразу в виде HTML-списка, чем массив, которое каждый раз нужно преобразовывать в HTML:

Сохранить значение recordset в виде HTML-списка

Кэшируйте данные на диске веб-сервера

Иногда в памяти вашего веб-сервера может быть слишком большое количество данных. «Слишком много», конечно, является спорным вопросом — это зависит от того, сколько памяти вы хотите использовать, а также число элементов для кэширования и частота, с которой эти элементы будут запрашиваться. В любом случае, если вы имеете слишком большое количество данных для кэширования в памяти, подумайте о переносе кэша в текстовый или XML-файл на жесткий диск веб-сервера. Вы можете одновременно комбинировать кэширование на диске и в памяти, чтобы сформировать оптимальную стратегию для вашего сайта.

Заметьте, что при измерении производительности одиночной ASP-страницы, получение данных с диска может не всегда быть быстрее, чем получение равноценных данных из БД. Но «файловое» кэширование уменьшает загрузку БД и сети, а при высокой загрузке БД до, значительно улучшит общую производительность после. Кэширование может быть очень эффективно при кэшировании результатов сложных запросов (например, соединение таблиц), трудоемких процедур сохранения, больших наборов записей. Чтобы убедится, насколько выгодным будет это решение требуется протестировать различные схемы сохранения.

ASP и COM обеспечивают несколько инструментальных средств для создания схем кэширования на диске. Функции набора записей ADO Save() и Open() сохраняют и загружают recordset c диска. Используя эти методы вы можете переписать код из прошлого совета, заменяя запись в объект Application на метод Save() для записи в файл.

Есть несколько других компонентов, которые работают с файлами:

Четыре уровня кэширования в сети: клиентский, сетевой, серверный и уровень приложения

В этой статье мы рассмотрим один из секретов высокой масштабируемости и производительности сайтов. Из блога об архитектуре Flickr, на серверах которого размещается более 5 000 000 фотографий, мы узнали, что кэширование и оперативная память играют ключевую роль в масштабируемости и производительности сайта.

Сайт может хранить данные для ускорения обработки последующих запросов на четырёх уровнях:

  • клиентский;
  • сетевой;
  • серверный;
  • уровень приложения.

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

Кэш на клиентском уровне

Заголовки HTTP отвечают за определение возможности кэширования ответа и за определение срока хранения данных. Следующий пример заголовка Cache-control указывает, что ответ может находиться в кэше в течение 7 дней. Браузер отправит повторный запрос на хранение данных, если срок хранения истечёт или пользователь целенаправленно обновит страницу.

Запрос и ответ, которые могут быть кэшированы в течение 604800 секунд.

Ответ также может включать заголовок Last-Modified или Etag . Эти заголовки нужны для проверки возможности повторного использования данных. Статус ответа 304 указывает, что содержимое не изменилось и повторная загрузка не требуется. Обратите внимание на парные заголовки Last-Modified и If-Modified-Since , а также на даты ниже:

Ответ с заголовком «Last-Modified» и последующим запросом с его использованием.

Заголовок Etag используется с If-None-Match аналогичным образом для обмена кодами ответа при определении изменений в контенте, если они имеются.

Сайт с продуманными HTTP-заголовками обретёт больший успех у пользователей. Кроме того, браузер сэкономит время и пропускную способность.

Кэш на сетевом уровне

Согласно Википедии, Сеть Доставки Контента (CDN) — географически распределённая сетевая инфраструктура, позволяющая оптимизировать доставку и дистрибуцию контента конечным пользователям в сети Интернет. Иначе говоря, CDN — это распределённое хранение и использование кэша.

Директива HTTP-заголовка Cache-control: public позволяет различным частям сети кэшировать ответ. С помощью заголовка Cache-Control: public, max-age=31536000 находят ресурсы, которые хранятся в течение одного года.

Возможно, вы уже знакомы с другими директивами заголовков. Существует также ещё один мощный заголовок, для обработки аутентифицированных и других видов динамических ответов.

Кэш на серверном уровне

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

Первый подход к более быстрым ответам и экономии ресурсов — настройка кэш-сервера между приложением и клиентом.

Клиенты, запрашивающие одно и то же содержимое на прокси-сервере.

Такие инструменты, как Varnish, Squid и nginx кэшируют изображения, скрипты и прочее содержимое, которое требуется пользователям. Следующая настройка nginx собирает кэш, опираясь только на HTTP-заголовки в приложении.

Существует ещё одна директива, которая называется proxy_cache_lock , которая позволяет прокси-серверу делегировать только первый из похожих клиентских запросов за один раз для приложения. Если директива установлена, клиенты будут получать ответ при возврате первого запроса.

Множество клиентов, запрашивающих одно и то же содержимое одновременно.

Этот простой, но мощный механизм позволяет избежать беспорядка на стороне приложения при большом количестве запросов, когда заканчивается срок хранения контента.

Идея последнего, но не менее важного подхода заключается в том, что прокси-сервер может улучшить отказоустойчивость приложения. Существуют флаги директивы proxy_cache_use_stale для доставки контента с истёкшим сроком актуальности, когда приложение возвращает статус ошибки или когда связь между прокси-сервером и приложением не работает должным образом.

В руководстве по кэшированию с NGINX и NGINX Plus содержится более подробная информация и параметры конфигурации.

Кэш на уровне приложения

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

Мемоизация

В приведённом выше коде на Ruby используется простой метод мемоизации, который сохраняет цену продукта, чтобы избежать дополнительных вычислений. Эта функция сохранит данные в экземпляре объекта и сэкономит ресурсы во время обработки запроса.

Эту функцию можно вызывать из любого места кода. Однако использование такой техники вызывает определённые проблемы. Важно помнить, что ваши данные не будут иметь срока актуальности. То есть глобальная мемоизация кода будет оставаться в памяти в течение всего цикла работы приложения.

Интеллектуальное кэширование в памяти

В приведённом выше коде используется API кэширования Rails для хранения и повторного использования метки категории в течение одной минуты во время обработки запросов. Ключом кэша для идентификации данных является category_id . Этот метод используется для экономии ресурсов, времени и уменьшения объёма запросов к внешней службе меток категорий.

Многие библиотеки предоставляют этот шаблон, но память приложения — не бесконечный ресурс. Например, менеджер кэша для Node не управляет объёмом потребляемой памяти. Также это может стать проблемой, если ваше приложение кэширует данные в больших объёмах, потребляя всю доступную память.

Кэширование данных Rails умным образом сокращает хранящиеся данные, когда они превышают выделенный размер памяти, удаляя давно неиспользуемые записи. Это позволяет кэшировать постоянные данные, не указывая срока их актуальности.

Совместное кэширование

Умение обращаться с растущим количеством пользователей и запросов — важный объект веб-разработки. Один из способов масштабирования приложения — добавление экземпляров приложения (горизонтальное масштабирование). Как вы, наверно, догадались, простой кэш в памяти не может использоваться несколькими экземплярами.

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

Хранилище со значениями ключей, такое как Memcached или Redis, может использоваться для совместного распределения данных кэша между экземплярами приложения. Эти инструменты имеют разные алгоритмы для сокращения количества кэшированных данных. Хранилища кэша также могут быть устойчивы к ошибкам с репликацией и хранением данных. Алгоритмы настолько сильно различаются, что Netflix создала свой собственный инструмент.

Ещё один важный аспект при использовании хранилищ кэша — это состояние гонки, которое происходит, когда разные экземпляры приложения обращаются к некэшированным данным одновременно. API кэширования запросов Rails содержит свойство race_condition_ttl для минимизации этого эффекта.

Упреждение состояния гонки для кэша с несколькими экземплярами приложений является сложной задачей. Оптимальным решением в этом случае выступает обновление данных кэша вне потока приложения и использование кэшированных данных в самом приложении. В архитектуре микросервиса можно защитить связь между приложением и сервисом с помощью nginx, как это описано выше.


Заключение

Надеемся, что эта статья поможет вам понять и выбрать лучшую стратегию для вашего приложения. HTTP-заголовки — это самое простое, что вы можете и должны настроить для оптимизации кэширования вашего приложения. Используйте также и другие стратегии, когда у вас появятся определённые проблемы в производительности, но помните, что преждевременная оптимизация — корень всех бед.

Полезные советы по оптимизации ASP-приложений. Кэшируйте часто используемые данные в объектах Application или Session

A few years back Phil Haack wrote a great article on the dangers of recurring background tasks in ASP.NET . In it he points out a few gotchas that are SO common when folks try to do work in the background. Read it, but here»s a summary from his post.

  • An unhandled exception in a thread not associated with a request will take down the process.
  • If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time.
  • The AppDomain your site runs in can go down for a number of reasons and take down your background task with it.

If you think you can just write a background task yourself, it»s likely you»ll get it wrong. I»m not impugning your skills, I»m just saying it»s subtle . Plus, why should you have to?

There»s LOT of great ways for you to do things in the background and a lot of libraries and choices available.

Some ASP.NET apps will be hosted in IIS in your data center and others will be hosted in the Azure cloud. The spectrum of usage is roughly this, in my opinion:

  • General: Hangfire (or similar similar open source libraries)
    • used for writing background tasks in your ASP.NET website
  • Cloud:
    • A formal Azure feature used for offloading running of background tasks outside of your Website and scale the workload
  • Advanced: Azure Worker Role in a Cloud Service
    • scale the background processing workload independently of your Website and you need control over the machine

There»s lots of great articles and videos on how to use , and lots of documentation on how Worker Roles in scalable Azure Cloud Services work, but not a lot about how your hosted ASP.NET application and easily have a background service. Here»s a few.

WebBackgrounder

As it says «WebBackgrounder is a proof-of-concept of a web-farm friendly background task manager meant to just work with a vanilla ASP.NET web application.» Its code hasn»t been touched in years, BUT the WebBackgrounder NuGet package has been downloaded almost a half-million times.

The goal of this project is to handle one task only, manage a recurring task on an interval in the background for a web app.

If your ASP.NET application just needs one background task to runs an a basic scheduled interval, than perhaps you just need the basics of WebBackgrounder.

Using System;
using System.Threading;
using System.Threading.Tasks;

namespace WebBackgrounder.DemoWeb
<
public class SampleJob: Job
<
public SampleJob(TimeSpan interval, TimeSpan timeout)
: base(«Sample Job», interval, timeout)
<
>

Public override Task Execute()
<
return new Task(() => Thread.Sleep(3000));
>
>
>

Built in: QueueBackgroundWorkItem — Added in .NET 4.5.2

Somewhat in response to the need for WebBackgrounder, .NET 4.5.2 added QueueBackgroundWorkItem as a new API . It»s not just a «Task.Run,» it tries to be more:

QBWI schedules a task which can run in the background, independent of any request. This differs from a normal ThreadPool work item in that ASP.NET automatically keeps track of how many work items registered through this API are currently running, and the ASP.NET runtime will try to delay AppDomain shutdown until these work items have finished executing.

It can try to delay an AppDomain for as long as 90 seconds in order to allow your task to complete. If you can»t finish in 90 seconds, then you»ll need a different (and more robust, meaning, out of process) technique.

The API is pretty straightforward, taking Func . Here»s an example that kicks of a background work item from an MVC action:

Public ActionResult SendEmail( User user)
<
if (ModelState.IsValid)
<
HostingEnvironment.QueueBackgroundWorkItem(ct => SendMailAsync(user.Email));
return RedirectToAction(«Index», «Home»);
>

FluentScheduler

FluentScheduler is a more sophisticated and complex scheduler that features a (you guessed it) fluent interface. You have really explicit control over when your tasks run.

public class MyRegistry: Registry
<
public MyRegistry()
<
// Schedule an ITask to run at an interval
Schedule ().ToRunNow().AndEvery(2).Seconds();

// Schedule a simple task to run at a specific time
Schedule(() => Console.WriteLine(«Timed Task — Will run every day at 9:15pm: » + DateTime.Now)).ToRunEvery(1).Days().At(21, 15);

// Schedule a more complex action to run immediately and on an monthly interval
Schedule(() =>
<
Console.WriteLine(«Complex Action Task Starts: » + DateTime.Now);
Thread.Sleep(1000);
Console.WriteLine(«Complex Action Task Ends: » + DateTime.Now);
>).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
>
>

FluentScheduler also embraces IoC and can easily plug into your favorite Dependency Injection tool of choice by just implementing their ITaskFactory interface.

Quartz.NET

Quartz.NET is a .NET port of the popular Java job scheduling framework of the (almost) same name. It»s very actively developed. Quartz has an IJob interface with just one method, Execute, to implement.

Using Quartz;
using Quartz.Impl;
using System;

namespace ScheduledTaskExample.ScheduledTasks
<
public class JobScheduler
<
public static void Start()
<
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();

IJobDetail job = JobBuilder.Create ().Build();

ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
.Build();

Then, inside your Application_Start, you call JobScheduler.Start(). There»s a great getting started article on Quartz at Mikesdotnetting you should check out.

Hangfire

And last but definitely not least, the most polished (IMHO) of the group,

Об опасностях выполнения фоновых задач в ASP.NET. Он выделил три основных риска, связанных с запуском фонового процесса:

  1. Необработанное исключение в потоке, несвязанном с запросом, может снять процесс.
  2. Если запустить сайт в веб-ферме, то есть вероятность случайно завершить несколько экземпляров приложения, которое могло запустить несколько экземпляров одной и той же задачи одновременно.
  3. Домен приложения, в котором запущен сайт, по разным причинам может выгрузиться и снять фоновую задачу, запущенную в нем.

Конечно, можно написать собственный менеджер для управления фоновыми задачами. Но, вероятнее всего, Вы сделаете это неправильно. Никто не собирается оспаривать Ваши навыки разработчика. Просто создание подобного менеджера — это достаточно тонкая вещь. Да и зачем Вам это надо?

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

Какие-то ASP.NET приложения могут работать на Ваших собственных серверах под IIS, какие-то размещаться в Azure.

Для запуска фоновых задач можно выделить несколько вариантов:

HANGFIRE

Документация Hangfire действительно превосходна. Хотелось бы, чтобы каждый проект с открытым исходным кодом имел такую документацию.

Одной из самых эффектных функций Hangfire является встроенная аналитическая панель, которая позволяет просматривать расписания, выполняющиеся задания, успешные и неуспешно завершенные задания.

Hangfire позволяет легко определить задачи типа «запустить и забыть», информация о которых будет храниться в базе данных:

BackgroundJob.Enqueue(() => Console.WriteLine(«Fire-and-forget»));
Можно отсрочить выполнение задачи:

BackgroundJob.Schedule(() => Console.WriteLine(«Delayed»), TimeSpan.FromDays(1));
Или запустить задачу в CRON стиле

RecurringJob.AddOrUpdate(() => Console.Write(«Recurring»), Cron.Daily);
Работать с Hangfire очень удобно. Hangfire имеет хорошую документацию и обучающие руководства , основанные на реальных примерах.

Hangfire — это целая экосистема для работы с фоновыми задачами в ASP.NET приложениях.

Библиотеки доступны в виде открытых исходных кодов или Nuget пакетов.

Итоги (лично от себя)

Я уже знаю, что мне нужно запускать больше одного процесса, и работать процессы могут долго (ограничение в 90 секунд на завершение в QueueBackgroundWorkItem). FluentScheduler выглядит неплохо, но хотелось большего. Hangfire – отличное решение, но, вроде, сразу требует использования базы данных для хранения очереди задач. Да и не совсем там все бесплатно – есть и платная версия.

В итоге я пока выбрал Quartz.NET: вполне приличная документация, достаточное количество примеров, чтобы быстро начать использовать, а также расширяемый функционал, который можно добавлять по мере возрастания потребностей.

Если вы знаете другие библиотеки для запуска фоновых задач или имеете опыт решения подобных задач – делитесь в комментариях.

АККОМПАНИРОВАТЬ accompagner ,> нем. akkompanieren . 1 . дипл. Приложить к чему-л., спроводить чем-л. (какую-л . посылку, отправление) . Я тот экстракт письмом своим не аккомпанировал. Кантемир Реляц. 2 172.

2. расш. Сопровождать кого-, что-л., быть дополнением к чему-л. Спинат, растение самое здоровое и для всякого желудка годное.. аккомпанирует все нарядные блюда. 1809. Гримо Прихотник 60. Однажды меня с Сазоновым (он мне всегда аккомпанирует в Ватикане) заперли. Гальберг Письма 57. Одни злословят по привычке, другие аккомпанируют. Ростопчин Ох, французы 114. Дежурный по полку ротмистр доказал, что ему хотелось есть и что аппетит у него богатырский, да и мы все аккомпанировали ему недурно, нечего сказать, не отказываясь от лафита и д»икема, которым, гостеприимный хозяин наполнял наши стаканы. В. П. Бурнашев Восп. // РА 1872 1839.

3. 1690. Лексис. муз. Сопровождать аккомпанементом. Акомпанировать своему голосу . Кн. муз. 52. Играть соло или аккомпанировать в сих концертах. Финдейз. 171. <Отец> играл на Виолончеле, и всегда акомпанировал наши Дуо. ММ 3 14. Он же Куликов фортепианами и арфою аккомпанирует. <Шарманщик> аккомпанирует вальс Ланнера свистками и трелями. Григорович Петерб. шарманщик. Он аккомпанировал Вьетану и многим певцам. Римский-Корс. Летопись. // РР 1970 1 60. || Припевать, подпевать . Но не было ли, спрашивает он, в вашем пении монотонии? Было, отвечает целомудренная супруга; но в финале все хорошо акомпанировали. Зритель 1 121. Хватайко поет и все акомпанируют: бери, большой тут нет науки. Капнист Ябеда 85.

4. перен. Сопровождая что-л., создавать определенный фон. БАС-2. Шепот продолжался, и ему аккомпанировал смущенно-счастливый смех. Мам.- Сиб. Черты из жизни Пепко. Собаки, смирно лежавшие у ворот, не выдерживали <визга поросят> и принялись аккомпанировать громким лаем и воем. А. Осипович Мечтатели. // ОЗ 1881 8 1 462. Лишь папа лесничий Дрожжинин шумно ел суточные щи, да мама для этикета аккомпанировала, едва разжимая строгие губы. Аксенов Затоварен. бочкотара. // РР 1970 3 60. — Лекс. Ян.1803: акомпанировать; Соколов 1834: акомпаниров а/ ть; Даль: акомпаниров а/ ть; САН 1933: аккомпан и/ ровать; Сл. 18: аккомпанировать 1734 (ако- 1792).

Исторический словарь галлицизмов русского языка. — М.: Словарное издательство ЭТС http://www.ets.ru/pg/r/dict/gall_dict.htm . Николай Иванович Епишкин [email protected] . 2010 .

Смотреть что такое «аккомпанировать» в других словарях:


АККОМПАНИРОВАТЬ — (фр. accompagner). Сопровождать пение игрою на каком либо музыкальном инструменте. Словарь иностранных слов, вошедших в состав русского языка. Чудинов А.Н., 1910. АККОМПАНИРОВАТЬ франц. accompagner. Сопровождать пение игрою на каком либо… … Словарь иностранных слов русского языка

аккомпанировать — См … Словарь синонимов

аккомпанировать — и устарелое аккомпанировать … Словарь трудностей произношения и ударения в современном русском языке

АККОМПАНИРОВАТЬ — АККОМПАНИРОВАТЬ, рую, руешь; несовер., кому. Исполнять аккомпанемент. А. на рояле. Толковый словарь Ожегова. С.И. Ожегов, Н.Ю. Шведова. 1949 1992 … Толковый словарь Ожегова

АККОМПАНИРОВАТЬ — кого или что (сонату) чем, на чем, муз., франц. вторить, сопровождать, подголашивать, подголосить, подыгрывать; держать другой, согласный голос. Аккомпанирование ср., ·длит. аккомпанировка жен., ·об. действие по гл., вторенье, подголоска,… … Толковый словарь Даля

аккомпанировать — (иноск. шут.) вторить, делать что в подражание другому, совместно с ним (намек на сопровождение пения или одного инструмента игрою одного или многих инструментов) Ср. Я издавна солист и аккомпанемента не ожидаю, один пью. Лесков. На ножах. 1,… … Большой толково-фразеологический словарь Михельсона

Аккомпанировать — несов. неперех. 1. Сопровождать игрой на музыкальном инструменте или на музыкальных инструментах сольную вокальную или инструментальную партию, основную тему или мелодию музыкального произведения. 2. перен. Создавать определённый фон, сопровождая … Современный толковый словарь русского языка Ефремовой

аккомпанировать — аккомпанировать, аккомпанирую, аккомпанируем, аккомпанируешь, аккомпанируете, аккомпанирует, аккомпанируют, аккомпанируя, аккомпанировал, аккомпанировала, аккомпанировало, аккомпанировали, аккомпанируй, аккомпанируйте, аккомпанирующий,… … Формы слов

аккомпанировать — аккомпан ировать, рую, рует … Русский орфографический словарь

аккомпанировать — (I), аккомпани/рую, руешь, руют … Орфографический словарь русского языка

Книги

  • Учись аккомпанировать на 6-струнной гитаре. От романсов к року и джазу , Манилов В.. В книге вы найдете необходимые сведения об аккордах, их последовательностях и способах усложнения партии ритм-гитары, о стандартной аппликатуре и типовых ритмических моделях различных жанров…

Последнее обновление: 10.03.2020

Одним из ключевых нововведений последних версий фреймворка.NET стала асинхронность. Хотя фреймворк и раньше позволял использовать асинхронные методы, но с появлением библиотеки Task Parallel Library работа с асинхронным кодом была предельно упрощена, а сам формат работы изменился. Были добавлены новые возможности по созданию асинхронных методов с использованием новых ключевых слов, таких как async и await.

При создании нового контроллера мы в настройках уже можем указать, как нам нужен контроллер — синхронный или асинхронный. По умолчанию Visual Studio добавляет в проект стандартные контроллеры, методы которых, как правило, возвращают объект ActionResult. Но если мы при добавлении контроллера в папку Controllers выберем тип MVC 5 Controller with views, using Entity Framework , то в окне настройки нового контроллера специальное поле позволит нам указать, что новый контроллер будет содержать асинхронные методы:

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

Чтобы понять различие между синхронными и асинхронными методами, рассмотрим, как IIS обрабатывает входящие запросы. Веб-сервер поддерживает пул потоков, которые обслуживают запросы. При обращении пользователя к веб-ресурсу IIS выделяет поток из пула для обслуживания данного запроса. И пока данный поток не обработает предназначенный для него запрос, другие запросы он обрабатывать не может.

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

И если обработка запроса блокируется очень долго, то IIS начинает задействовать для обслуживания других входящих запросов новые потоки. Однако есть ограничения на общее количество потоков. Когда количество потоков достигает предела, то вновь входящие запросы помещаются в очередь ожидания. Однако и тут есть ограничение на количество запросов в очереди. И когда это количество превышает предел, то IIS просто отклоняет все остальные запросы с помощью статусного кода 503 (Service Unavailable).

При асинхронной обработке поток не ждет, пока БД вернет ему данные, а начинает обрабатывать запрос от другого пользователя. Но когда, наконец, с сетевого ресурса или БД придут нужные данные, поток возвращается к обработке ранее обрабатываемого запроса в обычном режиме.

Перейдем непосредственно к коду. Для создания асинхронных методов используются модификаторы async и await , которые позволяют выполнять продолжительные операции без блокирования основного потока.

Сравним на примере вызов синхронного и асинхронного метода:

Using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using AsyncContollers.Models; using System.Threading.Tasks; using System.Data.Entity; namespace AsyncContollers.Controllers < public >books = db.Books; ViewBag.Books = books; return View(); > // асинхронный метод public async Task BookList() < IEnumerable books = await db.Books.ToListAsync(); ViewBag.Books = books; return View("Index"); >> >

Оба метода выполняют одну и ту же операцию — извлечение данных из БД и получают идентичные результаты. Но если первый синхронный метод Index представляет привычную для нас запись, то асинхронный метод BookList уже выглядит необычно.

Кроме того, чтобы обозначить метод как асинхронный, перед возвращаемым типом ставится ключевое слово async .

Третьим ключевым моментом является использование ключевого слова await . Оно применяется в асинхронных методах, чтобы приостановить выполнение этого метода до тех пор, пока ожидаемая задача не завершится. В нашем случае такой задачей является получение данных из БД.

Но также следует учитывать, что await используется с методами, возвращающими объект Task . Поэтому для получения данных из БД используется метод await db.Books.ToListAsync() , который также извлекает данные из БД, но уже в асинхронном режиме.

Когда следует использовать асинхронные методы? В первую очередь их предпочтительно использовать при запросах к БД, к внешнем сетевым ресурсам, однако в конечном счете, что лучше синхронность или асинхронность решает уже сам разработчик исходя из конкретной задачи.

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

Публикуемый ниже материал представляет собой первый совет из целой серии советов по оптимизации приложений, использующих технологии ASP и Visual Basic Scripting Edition (VBScript). Большинство из них были многократно обсуждены и c успехом проверены на веб-сайте Microsoft Corporation и других ASP-сайтах. Авторы материала подразумевают, что вы уже знакомы с основами разработки ASP-приложений, включая VBScript и/или JScript, ASP-сессиями и др. важными объектами (Request, Response и Server).

Кэшируйте часто используемые данные на сервере

Типичная ASP-страница получает данные из базы данных и затем выводит их в формате HTML. Независимо от скорости вашей базы данных, получение данных из памяти сервера намного быстрее, чем обработка sql-запроса к конечной базе данных. Получение данных, сохраненных на локальном жестком диске, также обычно быстрее, чем получение информации из БД. Поэтому одним из основных путей увеличения скорости работы вашей ASP-страницы является кэширование часто используемой информации в памяти или на жестком диске.

Кэширование данных — это классический компромисс «место или время». Если вы избрали для кэширования правильный материал, вы можете видеть внушительное повышение производительности вашего приложения. Чтобы кэширование было эффективным нужно использовать для временного хранения только те данные, которые многократно используются для вывода и каждый раз трудоемки для повторных вычислений. Кэш, полный устаревшей информации, будет пустой тратой памяти сервера.

Илон Маск рекомендует:  Что такое код settime

Данные, которые не изменяются часто, являются хорошим кандидатом для кэширования, потому что вам не надо будет волноваться относительно их синхронизации через какое-то время с конечной базой данных. Выпадающие списки (сombo-box), таблицы ссылок, пункты меню, и переменные конфигурации сайта (включая имена DSN, адреса IP и URL) — первые кандидаты для хранения в кэше. Заметьте, что вы можете кэшировать представление данных много быстрее, нежели данные сами себя. Если ASP-страница изменяется не так часто и ее временный кэш будет весьма внушительным (например, полный каталог изделий фирмы), попробуйте использовать сгенерированные HTML-страницы, чем каждый раз загружать сервер генерацией ASP-страниц.

Кэшируйте часто используемые данные в объектах Application или Session

Объекты Application и Session служат для хранения данных в памяти, значения которых могут быть доступны между несколькими HTTP-запросами (в отличие от обычных переменных, чьи значения доступны только в теле одной ASP-страницы). Данные объекта Session доступны только одному пользователю (в течении его сессии), в то время как данные Application доступны всем пользователям веб-сайта. Поэтому часто перед разработчиком возникает вопрос: в каком из объектов сохранять часто используемые данные. Обычно, для инициализации переменных этих объектов используются процедуры файла Global.asa — Application_OnStart() или Session_OnStart() соответственно. Если в вашем Global.asa еще нет этих процедур, то вы можете добавить их сами или инициализировать переменные, когда это будет необходимо. Примером может быть следующая процедура, использующая Application для хранения значений многократно использующейся переменной EmploymentStatusList. Процедура проверяет существование данных в EmploymentStatusList и при необходимости расчитывает их заново:

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

Function FetchEmploymentStatusList Dim rs Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status Получить все строки FetchEmploymentStatusList = rs.GetRows() rs.Close Set rs = Nothing End Function

Если полученный массив будет часто использоваться, тогда лучше хранить его сразу в виде HTML-списка, чем массив, которое каждый раз нужно преобразовывать в HTML:

Function FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status & vbCrLf rs.Close Set rs = Nothing FetchEmploymentStatusList = s End Function

Кэшируйте данные на диске веб-сервера

Иногда в памяти вашего веб-сервера может быть слишком большое количество данных. «Слишком много», конечно, является спорным вопросом — это зависит от того, сколько памяти вы хотите использовать, а также число элементов для кэширования и частота, с которой эти элементы будут запрашиваться. В любом случае, если вы имеете слишком большое количество данных для кэширования в памяти, подумайте о переносе кэша в текстовый или XML-файл на жесткий диск веб-сервера. Вы можете одновременно комбинировать кэширование на диске и в памяти, чтобы сформировать оптимальную стратегию для вашего сайта.

Заметьте, что при измерении производительности одиночной ASP-страницы, получение данных с диска может не всегда быть быстрее, чем получение равноценных данных из БД. Но «файловое» кэширование уменьшает загрузку БД и сети, а при высокой загрузке БД до, значительно улучшит общую производительность после. Кэширование может быть очень эффективно при кэшировании результатов сложных запросов (например, соединение таблиц), трудоемких процедур сохранения, больших наборов записей. Чтобы убедится, насколько выгодным будет это решение требуется протестировать различные схемы сохранения.

ASP и COM обеспечивают несколько инструментальных средств для создания схем кэширования на диске. Функции набора записей ADO Save() и Open() сохраняют и загружают recordset c диска. Используя эти методы вы можете переписать код из прошлого совета, заменяя запись в объект Application на метод Save() для записи в файл.

Есть несколько других компонентов, которые работают с файлами:

* Scripting.FileSystemObject позволяет создавать, читать и записывать файл.
* MSXML, MicrosoftR XML parser поддерживает сохранение и загрузку XML-документов.
* Объект LookupTable (например, используемый на MSN.com) — лучший выбор для загрузки простых списков с диска.

Наконец, рассмотрите вопрос принудительного кэширования информации на диске. Сгенерированный HTML-код может быть сохранен на диске как.htm или.asp файл; гиперссылки могут указывать прямо на этот файл. Вы можете автоматизировать процесс генерации HTML, используя коммерческие инструментальные средства типа XBuilder или средства публикации в Интернет, входящие в MicrosoftR SQL ServerT. Кроме того, при помощи директивы #include можно включать отдельные HTML-части в файл ASP или читать HTML-файл с диска используя FileSystemObject. Например, на начальной странице vbCode (http://vbcity.com/vbcode/ru/home.asp) приводятся 10 последних тем обсуждения двух дискуссионных форумов. Отобразить эти списки можно при помощи создания двух наборов записей ADO при каждом обращении к данной странице или, следуя данному совету, сохранить их однажды в виде HTML-файла list.inc, а затем включать в home.asp:

Второй путь работает значительно быстрее.

Избегайте кэшировать медленные компоненты в объектах Application или Session

Несмотря на то, что кэшированиe данных в объектах Application или Session может быть хорошей идеей, кэширование COM-объектов может иметь серьезные ловушки. Занесение наиболее используемых COM-объектов в объекты Application или Session часто соблазняет, но, к сожалению, много COM-объектов, включая все, написанные в Visual Basic 6.0 или ранее, могут вызывать серьезные критические проблемы после сохранения в объектах Application или Session.

В частности, любой компонент, который выполняется медленно, вызовет критические проблемы когда кэшируется в объектах Session или Application. Быстрый (проворный non-agile) компонент — компонент, помеченный ThreadingModel=Both, который объединен Free-threaded marshaler (FTM), или — компонент, помеченный ThreadingModel=Neutral. (Neutral — новая модель в WindowsR 2000 and COM+). Следующие компоненты не проворны:

* Free-threaded components.
* Apartment-threaded components.
* Single-threaded component.
* Configured components (библиотека Microsoft Transaction Server (MTS)/COM+ и серверные приложения) не проворны пока они Neutral-threaded. Apartment-threaded components и другие не проворные компоненты хорошо работают в пределах страницы (т.е. создаются и разрушаются в пределах одной ASP-страницы).

В IIS 4.0 компонент, отмеченный ThreadingModel=Both выполняется быстро. В IIS 5.0 уже не так достаточно. Компонент не должен только быть отмечен как Both, он должен также объединен FTM.

IIS выполняет проверку компонентов, но если вы хотите ее отменить (т.е. хотите позволить непроворным компонентам быть сохраненными в объектах Application или Session), вы можете установить AspTrackThreadingModel в metabase в значение True. Но это (изменение AspTrackThreadingModel) не рекомендуется.

IIS 5.0 выдаст сообщение об ошибке, если Вы пытаетесь сохранить непроворный компонент, созданный с использованием Server.CreateObject, в объекте Application. Вы можете обойти это, используя в Global.asa, но это также не рекомендуется, поскольку это ведет к проблемам (очереди и сериализация), объясняемым ниже.

Что же все-таки неправильно если вы кэшируете непроворные компоненты? Непроворный компонент, кэшируемый в объекте Session блокирует Session от других рабочих потоков (thread) ASP. ASP обслуживает пул (контейнер) рабочих потоков, запрашиваемых другими сервисами. Обычно, новый запрос обрабатывается первым доступным потоком. Если Session блокирована, то запрос должен ждать поток, когда он станет доступным. Проведем аналогию, которая поможет понять эту ситуацию: вы идете в магазин, выбираете несколько булок, и платите за них в кассе #3. Всякий раз, после того как вы выбрали булки в том магазине, вы всегда оплачиваете их в кассе #3, даже в том случае, когда в других кассах короче очередь или даже вообще нет покупателей.

Сохранение непроворных компонентов в объект Application накладывает столь же негативный эффект на производительность. ASP создает специальный поток для выполнения меделенных компонентов в пределах Application. Это имеет два последствия: все запросы выстраиваются в очередь к этому потоку и все запросы сериализуются. Выстраивание в очередь означает, что параметры были сохранены в общедоступной области памяти; запросы переключаются к специальному потоку; метод компонента выполнен; результаты выстраиваются в общедоступную область. Сериализация (преобразование в последовательную форму) означает, что все методы выполняются в одно время. Для двух различных потоков ASP не возможно одновременное выполнение методов общедоступного компонента. Это уничтожает многопотоковость (параллелизм), особенно на мультипроцессорных системах. Хуже всего то, что все непроворные компоненты в пределах Application совместно используют один поток («Host STA»), так что негативные результаты сериализации налицо.

Смущены? Есть некоторые общие правила. Если Вы пишете объекты в Visual Basic (6.0 или ранее), не храните их в объектах Application или Session. Если вы не знаете потоковую модель объекта, не храните его в кэше. Вместо кэширования где-либо непроворных объектов, вы должны создать и удалить их на каждой странице. Объекты выполнятся непосредственно в рабочем потоке ASP и не будет никакой очереди или сериализации. Производимость будет адекватна, если COM-объекты запущены под IIS и если они не используют много времени, чтобы инициализироваться и уничтожаться. Заметьте, что однопотоковые (single-threaded) объекты не должны использоваться этот путь. Будьте внимательным — VB может создавать однопотоковые объекты! Если вы используете однопотоковые объекты, этот путь (типа таблицы Microsoft Excel) не рассчитывает на высокую производительность.

Наборы записей (recordset) ADO могут безопасно кэшироваться когда ADO отмечен как Free-threaded. Чтобы сделать ADO как Free-threaded используйте файл Makfre15.bat, который обычно зафиксирован в каталоге Program FilesCommon FilesSystemADO.

Предупреждение: ADO не должен быть Free-threaded, если вы используете Microsoft Access в качестве БД. Набор записей ADO должен быть также вообще отсоединен, если вы не можете управлять конфигурацией ADO на вашем веб-сайте.

Не кэшируйте соединение БД в объектах Application или Session

Кэширование соединений ADO — обычно плохая стратегия. Если один объект Connection сохранен в объекте Application и используется на всех страницах, то все страницы будут бороться за использование этого соединения. Если объект Connection сохранен в ASP-объекте Session, то соединение БД будет создано для каждого пользователя. Это создает излишнюю загрузку веб-сервера и БД.

Вместо кэширования соединений БД, создавайте и уничтожайте объекты ADO на каждой ASP странице, которая использует ADO. Это эффективно, потому что IIS имеет встроенное подключение БД. Более точно, IIS автоматически допускает объединение подключений OLEDB и ODBC. Это гарантирует, что создание и уничтожение связей на каждой странице будут эффективны.

Так как соединенные наборы хранят ссылки на подключение БД, это следует, что вы должны не кэшировать соединенные наборы в объектах Application или Session. Однако, вы можете безопасно кэшировать отсоединенные наборы, которые не держат ссылку на подключение. Чтобы отсоединить набор записей, сделайте следующие два шага:

Set rs = Server.CreateObject(«ADODB.RecordSet») rs.CursorLocation = adUseClient » шаг 1 » Заполните recordset с данными rs.Open strQuery, strProv » Теперь отсоедините recordset от источника данных rs.ActiveConnection = Nothing » шаг 2

Подробную информацию относительно подключений смотрите в справочниках по ADO и SQL Server.

Разумное использование объекта Session

Теперь, когда в предыдущих советах были раскрыты достоинства кэширования данных в объектах Applications и Sessions, мы собираемся предложить вам избегать использования объекта Session. Сессии имеют несколько ловушек когда используются на загруженных сайтах. Под «загруженными» имеются ввиду сайты с сотнями запрашиваемых страниц в секунду или тысячами пользователей одновременно. Этот совет также важен для сайтов, которые должны масштабироваться горизонтально — т.е. те сайты, которые используют несколько серверов для распределения нагрузки и обеспечения отказоустойчивости при сбоях. Для меньших сайтов, типа intranet-сайтов, преимущества применения Sessions все же перевешивают.

Обобщая, ASP автоматически создает Session для каждого пользователя, который обращается к веб-серверу. Каждая сессия занимает приблизительно 10 Кб памяти (сверх любых данных, сохраненных в Session) и немного замедляет выполнение всех запросов. Сессия остается действующей до окончания таймаута (timeout), обычно 20 мин.

Но самая большая проблема при использовании сессий — это не производительность, а расширяемость. Сессии не охватывают все задействованные веб-сервера; как только Session была создана на одном сервере ее данные остаются там. Это означает, что если вы используете сессии на мультисерверном веб-сайте, вы должны придумать стратегию для обработки запросов каждого пользователя, которые должны быть всегда направлены на сервер, на котором существует сессия этого пользователя. Это называется «застреванием» пользователя на сервере (или «липкой сессией»).


Объект Application также не охватывает все сервера: если вам нужно совместно использовать и обновлять данные Application через веб-сервера, вам нужно использовать конечную базу данных. Однако неизменяемые (read-only) данные Application все же полезны на мультисерверных сайтах.

Наиболее критичные к скорости сайты обычно используют не менее двух веб-серверов. Поэтому при проектировании вашего ASP-приложения вы должны либо использовать «липкие сессии», либо просто избегать применения объекта Session, также как любых других методов, сохраняющих информацию пользователя на разных веб-серверах.

Если же вы не используете Session, то убедитесь, что отключили их. Это можно сделать посредством Internet Services Manager (см. документацию по ISM). Но если вам все-таки необходимо использовать сессии, то есть несколько путей уменьшить их удары про производительности.

Вы можете переместить содержимое, которое не требует сессий (например, страницы help и т.д.) в отдельное ASP-приложение, у которого сессии выключены. Кроме того, на страницах, где объект Session не используется, применяйте следующую директиву, помещещаемую вверху страницы:

Одна из основных причин ее применения — то, что Session создает интересную проблему в случае использования фрэймов (frameset). ASP гарантирует, что в любое время будет выполняться только один запрос от Session. Это делается для того, чтобы при одновременном запросе одним пользователем нескольких страниц, только один ASP-запрос был обработан сессией, что помогает избежать проблем многопоточного доступа к объекту Session. К сожалению, в результате этого все страницы в frameset будут загружаться последовательно, а не одновременно, и пользователю придется продолжительное время ждать полной загрузки. Мораль этой истории: если вы не уверены, что с использованием фрэймов и Session ваше приложение правильно работает, то используйте:

Альтернативой использованию объекта Session являются многочисленные параметры управления Session. При передаче малых объемов данных (менее 4 Кб) обычно рекомендуется использовать Cookies, переменные QueryString и скрытые (hidden) переменные форм. При использовании большого количества передаваемых параметров (например, корзина произведенных заказов в он-лайн магазине) наиболее лучший выбор — конечная база данных.

Статья будет полезна как новичкам, так и профессионалам. Первые получат сведения об основных возможностях MySQL, без чтения документации. А уже имея представление о…

Asp кэшируйте часто используемые данные на сервере

Обновлен: Ноябрь 2007

Часто приложение может повысить производительность с помощью хранения в памяти часто используемых данных, для создания которых требуется довольно долгое время обработки. Например, если приложение обрабатывает большие объемы данных, используя сложную логику, и затем возвращает данные в качестве отчета, к которому часто обращаются пользователи, будет эффективней избегать повторного создания отчета каждый раз, когда его запрашивает пользователь. Аналогично, если приложение содержит редко обновляющуюся страницу, обрабатывающую сложные данные, создавать эту страницу заново при каждом обращении будет неэффективно.

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

Кэш приложения предоставляет программный способ хранения произвольных данных в памяти с помощью пар «ключ-значение». Использование кэша приложения похоже на использование состояния приложения. Однако в отличие от состояния приложения, данные в кэше приложения изменяемы, что означает, что они не сохраняются в памяти в течение всего времени работы приложения. Преимущество использования кэша приложения состоит в том, что кэшем управляет платформа ASP.NET — она убирает элементы, когда истекает их срок действия, когда они становятся недействительны, или же когда остается мало памяти. Кэш приложения также может быть настроен для предупреждения приложения об удалении элемента. Дополнительные сведения см. в разделе Кэширование данных приложения .

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

Кэш вывода страницы сохраняет в памяти содержимое обработанной страницы ASP.NET. Это позволяет платформе ASP.NET посылать ответ страницы клиенту без выполнения повторного цикла обработки страницы. Кэш вывода страницы особенно полезен для редко меняющихся страниц, для создания которых требуется долгая обработка. Например, при создании веб-страницы с высоким трафиком, предназначенной для отображения редко обновляемой информации, кэш вывода страницы может сильно повысить производительность данной страницы. Кэш страницы может быть настроен для каждой страницы отдельно; также можно создать в файле Web.config профили кэширования, позволяющие однократно определить параметры кэширования и затем использовать их для нескольких страниц.

Кэш вывода страницы предоставляет два метода кэширования страницы: полное кэширование страницы и частичное кэширование страницы. Полное кэширование страницы позволяет сохранить все части страницы в памяти и использовать их для выполнения запроса клиента. Частичное кэширование страницы позволяет сохранить одни части страницы в кэше, в то время как другие части страницы остаются динамическими. Дополнительные сведения см. в разделе Кэширование страниц ASP.NET .

Частичное кэширование страницы может выполняться двумя способами: кэширование элементов управления и подстановка после кэширования. Кэширование элементов управления, также иногда называемое фрагментарным кэшированием, позволяет сохранять в кэше часть вывода страницы путем включения информации в пользовательский элемент управления и пометки пользовательского элемента как кэшируемого. Это позволяет кэшировать часть содержимого внутри страницы, в то время как вся страница целиком не кэшируется и каждый раз создается заново. Например, при создании страницы, отображающей большой объем динамического содержимого, такого как биржевая информация, но имеющей при этом статичные части, такие как итоги по торгам за неделю, можно поместить статичные части в пользовательские элементы и позволить им кэшироваться.

Подстановка после кэширования является противоположным по своему действию методом. Вся страница кэшируется, однако фрагменты страницы остаются динамическими. Например, если создать страницу, которая является статической в течение заданного периода времени, можно указать, что вся страница должна быть помещена в кэш. При добавлении на страницу элемента управления Label , который отображает имя пользователя, элемент управления Label будет оставаться одним и тем же при каждом обновлении страницы и для каждого пользователя, отображая имя пользователя, запросившего страницу перед ее кэшированием. Тем не менее, при использовании подстановки после кэширования всю страницу можно поместить в кэш, но при этом отметить отдельные части страницы как некэшируемые. В таком случае можно добавить элементы управления Label в некэшируемую часть, и они будут создаваться динамически для каждого пользователя при каждом запросе страницы. Дополнительные сведения см. в разделе Кэширование частей страницы ASP.NET .

Кэширование страниц на основе параметров запроса

В дополнение к кэшированию единственной версии страницы кэширование вывода страницы ASP.NET предоставляет возможности по созданию нескольких версий страницы, различающихся по параметрам запроса. Дополнительные сведения см. в разделе Кэширование нескольких версий страницы .

Платформа ASP.NET может удалить данные из кэша по одной из следующих причин:

На сервере не хватает памяти (этот процесс называется очисткой).

Истек срок действия элемента в кэше.

Изменилась зависимость элемента.

Упрощая управление кэшированными элементами, платформа ASP.NET может уведомлять приложение об удалении элементов из кэша.

Очистка

Очистка — это процесс удаления элементов из кэша при нехватке памяти. Элементы удаляются, если к ним долгое время не было обращений, или же если элементы при добавлении в кэш были помечены как низкоприоритетные. Для определения тех элементов, которые нужно удалить в первую очередь, ASP.NET использует объект CacheItemPriority . Дополнительные сведения см. в разделе Практическое руководство. Добавление элементов в объект Cache .

Истечение срока действия

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

Тип срока действия

Скользящий срок действия

Определяет срок действия элемента со времени последнего обращения. Например, можно задать истечение срока действия элемента спустя 20 минут после последнего обращения к нему в кэше.

Абсолютный срок действия

Определяет срок действия предмета независимо от частоты обращений. Например, можно задать истечение срока действия элемента в 18:00 или же спустя четыре часа.

Зависимости

Можно настроить срок хранения элемента в кэше в зависимости от других элементов приложения, таких как файлы или базы данных. При изменении элемента, от которого зависит элемент в кэше, ASP.NET удаляет элемент из кэша. Например, если веб-узел отображает отчет, созданный приложением по XML-файлу, можно поместить данный отчет в кэш и настроить его так, чтобы он зависел от XML-файла. Когда XML-файл будет изменен, ASP.NET удалит отчет из кэша. Когда код запросит отчет, код сначала определит, находится ли отчет в кэше, и если нет — код создаст его. Таким образом, всегда будет доступна самая последняя версия отчета.

Кэш ASP.NET поддерживает зависимости, описанные в следующей таблице.

Зависимость по ключу

Элементы в кэше приложения хранятся в парах «ключ-значение». Зависимость по ключу позволяет элементу зависеть от ключа другого элемента в кэше приложения. Когда исходный элемент удаляется, удаляется также и элемент, имеющий зависимость по ключу. Например, можно добавить в кэш элемент с именем ReportsValid и кэшировать несколько отчетов, зависимых от ключа ReportsValid . Когда элемент ReportsValid будет удален из кэша, все зависимые кэшированные отчеты также будут удалены из кэша.

Зависимость от файла

Элемент в кэше зависит от внешнего файла. Если файл изменится или будет удален, кэшированный элемент будет удален.

Зависимость от SQL

Элемент в кэше зависит от изменений в таблице базы данных Microsoft SQL Server 2005, SQL Server 2000 или SQL Server 7.0. В случае SQL Server 2005 элемент может зависеть от строки в таблице. Дополнительные сведения см. в разделе Кэширование в ASP.NET с помощью класса SqlCacheDependency .

Зависимость от статистического выражения

Элемент в кэше зависит от нескольких элементов; зависимость при этом задается с помощью класса AggregateCacheDependency . Если зависимости будут каким-либо образом изменены, элемент будет удален из кэша.

Элемент в кэше настраивается на зависимость, созданную в коде разработчика. Например, можно создать настраиваемую зависимость кэша от веб-службы, при которой данные из кэша будут удаляться, если вызов веб-службы возвращает определенное значение.

Приложение может получать уведомления об удалении элемента из кэша приложения. Например, если имеется элемент, требующий для создания большое количество времени обработки, уведомления о его удалении из кэша можно использовать для того, чтобы немедленно заменить его. В результате в следующий раз при запросе элемента пользователю не придется ждать обработки элемента. Дополнительные сведения см. в разделе Практическое руководство. Уведомление приложения об удалении элемента из кэша .

Распределенное кэширование в ASP.NET Core Distributed caching in ASP.NET Core

Распределенный кэш — это кэш, совместно используемый несколькими серверами приложений, обычно поддерживаемый как внешняя служба для серверов приложений, обращающихся к ней. A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. Распределенный кэш может повысить производительность и масштабируемость приложения ASP.NET Core, особенно если приложение размещено в облачной службе или ферме серверов. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.

Распределенный кэш имеет несколько преимуществ по сравнению с другими сценариями кэширования, в которых кэшированные данные хранятся на отдельных серверах приложений. A distributed cache has several advantages over other caching scenarios where cached data is stored on individual app servers.

При распределении кэшированных данных данные: When cached data is distributed, the data:

  • — Согласованность между запросами к нескольким серверам. Is coherent (consistent) across requests to multiple servers.
  • Выдерживает перезапуски сервера и развертывание приложений. Survives server restarts and app deployments.
  • Не использует локальную память. Doesn’t use local memory.

Конфигурация распределенного кэша зависит от конкретной реализации. Distributed cache configuration is implementation specific. В этой статье описывается настройка распределенных кэшей SQL Server и Redis. This article describes how to configure SQL Server and Redis distributed caches. Также доступны реализации сторонних производителей, например NCache (NCache на GitHub). Third party implementations are also available, such as NCache (NCache on GitHub). Независимо от выбранной реализации приложение взаимодействует с кэшем с помощью IDistributedCache интерфейса. Regardless of which implementation is selected, the app interacts with the cache using the IDistributedCache interface.

Предварительные требования Prerequisites

Чтобы использовать SQL Server распределенный кэш, добавьте ссылку на пакет в пакет Microsoft. Extensions. Caching. SqlServer . To use a SQL Server distributed cache, add a package reference to the Microsoft.Extensions.Caching.SqlServer package.

Чтобы использовать распределенный кэш Redis, добавьте ссылку на пакет в пакет Microsoft. Extensions. Caching. стаккексчанжередис . To use a Redis distributed cache, add a package reference to the Microsoft.Extensions.Caching.StackExchangeRedis package.

Чтобы использовать SQL Server распределенный кэш, укажите ссылку на Microsoft. AspNetCore. app метапакет или добавьте ссылку на пакет Microsoft. Extensions. Caching. SqlServer . To use a SQL Server distributed cache, reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Caching.SqlServer package.

Чтобы использовать распределенный кэш Redis, укажите ссылку на Microsoft. AspNetCore. app метапакет и добавьте ссылку на пакет Microsoft. Extensions. Caching. стаккексчанжередис . To use a Redis distributed cache, reference the Microsoft.AspNetCore.App metapackage and add a package reference to the Microsoft.Extensions.Caching.StackExchangeRedis package. Пакет Redis не входит в Microsoft.AspNetCore.App пакет, поэтому необходимо отдельно ссылаться на пакет Redis в файле проекта. The Redis package isn’t included in the Microsoft.AspNetCore.App package, so you must reference the Redis package separately in your project file.

Чтобы использовать SQL Server распределенный кэш, укажите ссылку на Microsoft. AspNetCore. app метапакет или добавьте ссылку на пакет Microsoft. Extensions. Caching. SqlServer . To use a SQL Server distributed cache, reference the Microsoft.AspNetCore.App metapackage or add a package reference to the Microsoft.Extensions.Caching.SqlServer package.

Чтобы использовать распределенный кэш Redis, укажите ссылку на Microsoft. AspNetCore. app метапакет и добавьте ссылку на пакет Microsoft. Extensions. Caching. Redis . To use a Redis distributed cache, reference the Microsoft.AspNetCore.App metapackage and add a package reference to the Microsoft.Extensions.Caching.Redis package. Пакет Redis не входит в Microsoft.AspNetCore.App пакет, поэтому необходимо отдельно ссылаться на пакет Redis в файле проекта. The Redis package isn’t included in the Microsoft.AspNetCore.App package, so you must reference the Redis package separately in your project file.

Интерфейс IDistributedCache IDistributedCache interface

IDistributedCache Интерфейс предоставляет следующие методы для управления элементами в реализации распределенного кэша: The IDistributedCache interface provides the following methods to manipulate items in the distributed cache implementation:

  • Get, GetAsync byte[] Принимает строковый ключ и получает кэшированный элемент в виде массива, если он найден в кэше. – Get, GetAsync – Accepts a string key and retrieves a cached item as a byte[] array if found in the cache.
  • Set byte[] , SetAsync Добавляет– элемент (в виде массива) в кэш с помощью строкового ключа. Set, SetAsync – Adds an item (as byte[] array) to the cache using a string key.
  • RefreshRefreshAsync Обновляетэлементвкэшенаосновеегоключа,переустанавливаяскользящийтайм-аутистечениясрокадействия(– если он есть). Refresh, RefreshAsync – Refreshes an item in the cache based on its key, resetting its sliding expiration timeout (if any).
  • RemoveRemoveAsync ,– Удаляет элемент кэша на основе его строкового ключа. Remove, RemoveAsync – Removes a cache item based on its string key.

Установка служб распределенного кэширования Establish distributed caching services

Зарегистрируйте реализацию IDistributedCache в Startup.ConfigureServices . Register an implementation of IDistributedCache in Startup.ConfigureServices . Реализации, предоставляемые платформой, описанные в этом разделе, включают: Framework-provided implementations described in this topic include:

Кэш распределенной памяти Distributed Memory Cache

Кэш распределенной памяти (AddDistributedMemoryCache) — это предоставляемая платформой IDistributedCache реализация, которая хранит элементы в памяти. The Distributed Memory Cache (AddDistributedMemoryCache) is a framework-provided implementation of IDistributedCache that stores items in memory. Кэш распределенной памяти не является фактическим распределенным кэшем. The Distributed Memory Cache isn’t an actual distributed cache. Кэшированные элементы хранятся в экземпляре приложения на сервере, где выполняется приложение. Cached items are stored by the app instance on the server where the app is running.

Кэш распределенной памяти — это полезная реализация: The Distributed Memory Cache is a useful implementation:

  • В сценариях разработки и тестирования. In development and testing scenarios.
  • Если в рабочей среде используется один сервер, а использование памяти не является проблемой. When a single server is used in production and memory consumption isn’t an issue. Реализация кэша распределенной памяти абстрагирует хранилище кэшированных данных. Implementing the Distributed Memory Cache abstracts cached data storage. Она позволяет реализовать истинное решение распределенного кэширования в будущем, если потребуется несколько узлов или отказоустойчивость. It allows for implementing a true distributed caching solution in the future if multiple nodes or fault tolerance become necessary.


Пример приложения использует распределенный кэш памяти при запуске приложения в среде разработки в Startup.ConfigureServices : The sample app makes use of the Distributed Memory Cache when the app is run in the Development environment in Startup.ConfigureServices :

Распределенный кэш SQL Server Distributed SQL Server Cache

Реализация кэша распределенного SQL Server (AddDistributedSqlServerCache) позволяет распределенному кэшу использовать базу данных SQL Server в качестве резервного хранилища. The Distributed SQL Server Cache implementation (AddDistributedSqlServerCache) allows the distributed cache to use a SQL Server database as its backing store. Чтобы создать SQL Server таблицу кэшированных элементов в экземпляре SQL Server, можно использовать sql-cache средство. To create a SQL Server cached item table in a SQL Server instance, you can use the sql-cache tool. Средство создает таблицу с указанными именем и схемой. The tool creates a table with the name and schema that you specify.

Создайте таблицу в SQL Server, выполнив sql-cache create команду. Create a table in SQL Server by running the sql-cache create command. Укажите Data Source SQL Server экземпляр (), базу данных ( Initial Catalog ), схему (например, dbo ) и имя таблицы (например, TestCache ): Provide the SQL Server instance ( Data Source ), database ( Initial Catalog ), schema (for example, dbo ), and table name (for example, TestCache ):

В журнал заносится сообщение, указывающее, что средство прошло успешно: A message is logged to indicate that the tool was successful:

Таблица, созданная sql-cache средством, имеет следующую схему: The table created by the sql-cache tool has the following schema:

Приложение должно манипулировать значениями кэша с помощью экземпляра IDistributedCache, а SqlServerCacheне. An app should manipulate cache values using an instance of IDistributedCache, not a SqlServerCache.

Пример приложения реализует SqlServerCache в среде, не являющейся средой разработки Startup.ConfigureServices , в: The sample app implements SqlServerCache in a non-Development environment in Startup.ConfigureServices :

ConnectionString (И, при необходимости, SchemaName и TableName) обычно хранятся вне системы управления версиями (например, хранится в диспетчере секретов или в appsettings.json/appsettings. <Файлы среды>. JSON ). A ConnectionString (and optionally, SchemaName and TableName) are typically stored outside of source control (for example, stored by the Secret Manager or in appsettings.json/appsettings..json files). Строка подключения может содержать учетные данные, которые должны содержаться в системе управления версиями. The connection string may contain credentials that should be kept out of source control systems.

Распределенный кэш Redis Distributed Redis Cache

Redis -это хранилище данных в памяти с открытым исходным кодом, которое часто используется в качестве распределенного кэша. Redis is an open source in-memory data store, which is often used as a distributed cache. Вы можете использовать Redis локально, и вы можете настроить кэш Redis для Azure для приложения ASP.NET Core, размещенного в Azure. You can use Redis locally, and you can configure an Azure Redis Cache for an Azure-hosted ASP.NET Core app.

Приложение настраивает реализацию кэша с помощью RedisCache экземпляра (AddStackExchangeRedisCache) в среде, не являющейся средой разработки, Startup.ConfigureServices в: An app configures the cache implementation using a RedisCache instance (AddStackExchangeRedisCache) in a non-Development environment in Startup.ConfigureServices :

Приложение настраивает реализацию кэша с помощью RedisCache экземпляра (AddStackExchangeRedisCache) в среде, не являющейся средой разработки, Startup.ConfigureServices в: An app configures the cache implementation using a RedisCache instance (AddStackExchangeRedisCache) in a non-Development environment in Startup.ConfigureServices :

Приложение настраивает реализацию кэша с помощью RedisCache экземпляра (AddDistributedRedisCache): An app configures the cache implementation using a RedisCache instance (AddDistributedRedisCache):

Чтобы установить Redis на локальном компьютере, выполните следующие действия. To install Redis on your local machine:

  • Установите пакет шоколадного Redis. Install the Chocolatey Redis package.
  • Запустите redis-server из командной строки. Run redis-server from a command prompt.

Использование распределенного кэша Use the distributed cache

Чтобы использовать IDistributedCache интерфейс, запросите IDistributedCache экземпляр из любого конструктора в приложении. To use the IDistributedCache interface, request an instance of IDistributedCache from any constructor in the app. Экземпляр предоставляется путем внедрения зависимостей (DI). The instance is provided by dependency injection (DI).

При запуске IDistributedCache примера приложения внедряется в Startup.Configure . When the sample app starts, IDistributedCache is injected into Startup.Configure . Текущее время кэшируется с помощью IHostApplicationLifetime (Дополнительные сведения см. в разделе универсальный узел: Ихостаппликатионлифетиме): The current time is cached using IHostApplicationLifetime (for more information, see Generic Host: IHostApplicationLifetime):

При запуске IDistributedCache примера приложения внедряется в Startup.Configure . When the sample app starts, IDistributedCache is injected into Startup.Configure . Текущее время кэшируется с помощью IApplicationLifetime (Дополнительные сведения см. в разделе веб-узел: Интерфейсиаппликатионлифетиме): The current time is cached using IApplicationLifetime (for more information, see Web Host: IApplicationLifetime interface):

Пример приложения внедряет IDistributedCache в объект IndexModel для использования на странице индекса. The sample app injects IDistributedCache into the IndexModel for use by the Index page.

При каждой загрузке страницы индекса кэш проверяется на наличие кэшированного времени в OnGetAsync . Each time the Index page is loaded, the cache is checked for the cached time in OnGetAsync . Если время кэширования не истекло, отображается время. If the cached time hasn’t expired, the time is displayed. Если прошло 20 секунд с момента последнего обращения к кэшированному времени (время последней загрузки этой страницы), на странице отображается время ожидания кэширования. If 20 seconds have elapsed since the last time the cached time was accessed (the last time this page was loaded), the page displays Cached Time Expired.

Немедленно обновите кэшированное время на текущее время, нажав кнопку сбросить кэшированное время. Immediately update the cached time to the current time by selecting the Reset Cached Time button. Кнопка запускает OnPostResetCachedTime метод обработчика. The button triggers the OnPostResetCachedTime handler method.

Время жизни экземпляров IDistributedCache (по крайней мере, для встроенных реализаций) не обязательно должно быть ограничено одним объектом или блоком. There’s no need to use a Singleton or Scoped lifetime for IDistributedCache instances (at least for the built-in implementations).

Кроме того, IDistributedCache экземпляр можно создать везде, где вам может понадобиться, а не использовать di, но создание экземпляра в коде может усложнить тестирование и нарушает принцип явных зависимостей. You can also create an IDistributedCache instance wherever you might need one instead of using DI, but creating an instance in code can make your code harder to test and violates the Explicit Dependencies Principle.

Рекомендации Recommendations

При принятии решения о том, IDistributedCache какая реализация лучше подходит для вашего приложения, учитывайте следующее. When deciding which implementation of IDistributedCache is best for your app, consider the following:

  • Существующая инфраструктура Existing infrastructure
  • Требования к производительности Performance requirements
  • Стоимость Cost
  • Опыт работы в группе Team experience

Для обеспечения быстрого извлечения кэшированных данных решения кэширования обычно используют хранилище в памяти, но память является ограниченным ресурсом и может быть расширена. Caching solutions usually rely on in-memory storage to provide fast retrieval of cached data, but memory is a limited resource and costly to expand. Хранение часто используемых данных в кэше. Only store commonly used data in a cache.

Как правило, кэш Redis обеспечивает более высокую пропускную способность и меньшую задержку, чем кэш SQL Server. Generally, a Redis cache provides higher throughput and lower latency than a SQL Server cache. Однако для определения характеристик производительности стратегий кэширования обычно требуется тестирование производительности. However, benchmarking is usually required to determine the performance characteristics of caching strategies.

Если SQL Server используется в качестве резервного хранилища распределенного кэша, использование той же базы данных для кэша и обычного хранилища данных и извлечения приложения может негативно сказаться на производительности обоих. When SQL Server is used as a distributed cache backing store, use of the same database for the cache and the app’s ordinary data storage and retrieval can negatively impact the performance of both. Рекомендуется использовать выделенный экземпляр SQL Server для резервного хранилища распределенного кэша. We recommend using a dedicated SQL Server instance for the distributed cache backing store.

Работа с распределенным кэшем¶

Распределенный кэш может улучшить производительность и масштабируемость ASP.NET 5 приложения, особенно если оно хостится на облаке или ферме. В данной статье рассказывается, как работать со встроенными в ASP.NET 5 абстракциями и реализациями распределенного кэша.

Что такое распределенный кэш¶

Распределенный кэш используют несколько серверов (см. Caching Basics ). Кэшированная информация не хранится в памяти отдельного сервера, а кэшированные данные доступны всем серверам. Здесь есть несколько преимуществ:

  1. Кэшированные данные связаны на всех серверах. Пользователи видят одинаковый результат, независимо от того, к какому серверу они делают запрос.
  2. Перезагрузки серверов не влияют на кэшированные данные. Отдельные сервера могут быть удалены или добавлены, не влияя на кэш.
  3. К хранилищу исходных данных делается меньше запросов.

При использовании распределенного кэша SQL Server некоторые из этих преимуществ верны только тогда, когда используются определенные экземпляры БД для кэша и исходных данных.

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

Конфигурация кэша зависит от реализации. В этой статье рассказывается, как настроить распределенный кэш в Redis и SQL Server. Независимо от выбранной реализации, приложение работает с кэшем с помощью интерфейса IDistributedCache.

Интерфейс IDistributedCache¶

Интерфейс IDistributedCache включает в себя синхронные и асинхронные методы. Интерфейс позволяет добавлять, извлекать и удалять элементы из кэша. Вот методы IDistributedCache :

Connect, ConnectAsync устарел Get, GetAsync Принимает строковый ключ и извлекает кэшированный элемент как byte[] , если таковой есть в кэше. Set, SetAsync Добавляет в кэш элемент (как byte[] ) с помощью строкового ключа. Refresh, RefreshAsync Обновляет элемент, сбрасывая его таймаут. Remove, RemoveAsync Удаляет запись по кэшу в зависимости от ее ключа.

Чтобы использовать IDistributedCache :

  1. Укажите необходимые зависимости в project.json .
  2. Настройте конкретную реализацию IDistributedCache в методе Startup ConfigureServices и добавьте его в контейнер.
  3. Из классов Связующее ПО (M > IDistributedCache из конструктора. Экземпляр будет предоставлен Внедрение зависимостей (Dependency Injection) (DI).

Для экземпляров IDistributedCache нет необходимости использовать Singleton или Scoped (как минимум, для встроенных реализаций). Вы также можете создать экземпляр в любое время, когда он вам нужен (вместо использования Внедрение зависимостей (Dependency Injection)), но тогда ваш код будет сложнее тестировать и будет нарушен принцип явных зависимостей.

Вот как использовать экземпляр IDistributedCache в простом компоненте связующего ПО:

В коде сверху кэшированные значения считываются, но не записываются. В этом примере значение устанавливается при запуске сервера и не меняется. При сценарии с несколькими серверами серверы, которые запускаются позже, перепишут предыдущие значения. Методы Get и Set используют тип byte[] . Поэтому строковое значение должно быть конвертировано с помощью Encoding.UTF8.GetString (для Get ) и Encoding.UTF8.GetBytes (для Set ).

Далее представлены установленные из Startup.cs значения:

Поскольку IDistributedCache настраивается в методе ConfigureServices , и он доступен в качестве параметра для метода Configure . И тогда с настроенным экземпляром можно работать с помощью DI.

Распределенный кэш Redis¶

Redis — это хранилище данных in-memory с открытым исходным кодом, которое часто используется для распределенного кэша. Вы можете использовать его локально, а также вы можете настроить Azure Redis Cache для приложений, размещенных на Azure. Реализация кэша настраивается с помощью интерфейса RedisDistributedCache .

Реализация Redis настраивается в ConfigureServices и получает доступ к вашему коду, запрашивая экземпляр IDistributedCache (см. код выше).

В нашем примере реализация RedisCache используется тогда, когда сервер настроен на среду Staging . Метод ConfigureStagingServices настраивает RedisCache :

Чтобы установить Redis на локальном компьютере, установите пакет http://chocolatey.org/packages/redis-64/ и запустите из командной строки redis-server .

Использование распределенного кэша для SQL Server¶

Реализация SqlServerCache позволяет распределенному кэшу использовать SQL Server. Скрипт устанавливает таблицу с указанным вами именем. Вот схема таблицы:

Если вы работаете с версией RC1 SqlServerCache , то у вас не будет работающего установщика. Вы можете установить требуемую таблицу с помощью скриптов, расположенных здесь: файл SqlQueries.cs. Это разрешается в RC2.

Как и при всех реализациях кэша, ваше приложение должно получать и устанавливать кэшированные значения с помощью экземпляра IDistributedCache , а не SqlServerCache . В примере реализован SqlServerCache в среде Production (настроенной в ConfigureProductionServices ).

ConnectionString (и дополнительно SchemaName и TableName ) должны храниться вне source control (например, UserSecrets), поскольку они могут хранить чувствительные данные.

Рекомендации¶

Когда вы принимаете решение, какая реализация IDistributedCache подходит для вашего приложения, выбирайте Redis и SQL Server, основываясь на существующей инфраструктуре и среде, а также требованиях по производительности. Если вашей команде больше нравится работать с Redis — это отличный выбор. Если же ваша команда предпочитает SQL Server, вы можете использовать эту реализацию. Традиционное кэширование сохраняет данные in-memory, что позволяет их быстро извлекать. Вы должны хранить часто используемые данные в кэше, a все данные в таком хранилище, как SQL Server или Azure Storage. Кэширование Redis предлагает более высокую пропускную способность и низкую латентность по сравнению с SQL кэшированием. Также вам стоит избегать реализации in-memory ( MemoryCache ) на нескольких серверах.

Реализация in-memory IDistributedCache должна использоваться только для тестирования приложения, расположенного на одном сервере.

IT-ЗАМЕТКИ

Инструменты пользователя

Инструменты сайта


Содержание

На основе этих моделей построены также два специализированных типа кэширования.

Кэширование вывода

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

Декларативное кэширование вывода

Существуют два способа добавить страницу в кэш вывода. Наиболее распространенный подход заключается во вставке директивы OutputCache в начало файла .aspx, непосредственно под директивой Page:

В этом примере атрибут Duration инструктирует ASP .NET о том, что страницу нужно хранить в кэше в течение 20 секунд.

В рассматриваемом примере атрибут VaryByParam устанавливается в None. Это сообщает ASP .NET, что мы хотим хранить только одну копию кэшируемой страницы, которая подходит для всех сценариев.

Кэширование и строка запроса

Значение атрибута VaryByParam можно установить в «*», указав, что страница использует строку запроса, и таким образом проинструктировать ASP .NET о том, что нужно кэшировать отдельные копии страницы для разных значений аргументов в строке запроса:

Кэширование со специфичными параметрами строки запроса

Установка VaryByParam=«*» позволяет использовать кэширование с динамическими страницами, которые варьируют свой вывод в зависимости от строки запроса. Этот подход может быть исключительно полезен для детальной страницы товара, которая принимает идентификатор товара в строке запроса. При кэшировании с варьированием параметров можно сохранять отдельную страницу для каждого товара, таким образом, экономя на обращениях к базе данных. Однако чтобы получить выигрыш в производительности, может понадобиться увеличить время существования кэшированного вывода до нескольких минут или больше.

Во многих ситуациях установка VaryByParam=«*» вносит ненужную неопределенность. Обычно лучше специально идентифицировать важную переменную строки запроса по имени. Вот пример:

В этом случае будут кэшироваться отдельные версии выходной страницы, если строка запроса отличается по ProductID или CurrencyType.

Кэширование с помощью класса HttpCachePolicy

Однако есть и другой выбор: можно написать код, использующий специальное встроенное свойство Response.Cache, которое предоставляет экземпляр класса System.Web. HttpCachePolicy. Этот объект содержшнсвойства, позволяющие включать кэширование для текущей страницы. Это позволяет программно решить, нужно ли включать кэширование вывода.

Послекэшевая подстановка

Средство послекэшевой подстановки вращается вокруг единственного метода, добавленного в класс HttpResponse. Этот метод называется WriteSubstitution() и принимает один параметр — делегат, указывающий на метод обратного вызова, который вы реализуете в своем классе страницы. Метод обратного вызова возвращает содержимое этой части страницы.

Теперь, даже если применить кэширование к этой странице с помощью директивы OutputCache, вторая дата, отображаемая на странице, все равно будет обновляться при каждом запросе, потому что обратный вызов минует процесс кэширования.

Конфигурация кэша

Для конфигурирования этих настроек используется элемент внутри описанного ранее элемента . Элемент предоставляет несколько опций для настройки:

Используйте disableMemoryCollection и disableExpiration для прекращения сбора элементов ASP .NET, когда объем свободной памяти ограничен (процесс называется очисткой), и удаления устаревших элементов.

Кэширование юзер контрола

Кэширование данных

Кэширование данных — наиболее гибкий тип кэширования, однако для своей реализации он требует выполнения в коде ряда дополнительных шагов. Базовый принцип кэширования данных состоит в добавлении элементов, создание которых обходится дорого, в специальный встроенный объект коллекции (называемый Cache). Этот объект работает во многом подобно объекту Application. Он доступен глобально всем запросам от всех клиентов в приложении. Однако существуют несколько ключевых отличий.

Как и состояние приложения, кэшируемый объект привязан к процессу. Это означает, что он не должен существовать после перезапуска домена приложения, и не может быть разделен между компьютерами в веб-серверном кластере. Такое поведение заложено при проектировании, потому что цена, которую пришлось бы заплатить за предоставление возможности многим компьютерам взаимодействовать с внепроцессным кэшем, свела бы на нет выигрыш в производительности. Поэтому больше смысла позволить каждому веб-серверу иметь собственный кэш.

Добавление элементов в кэш

Более предпочтительный подход добавления кеша в память это применении метода Insert():

Перегрузка Описание
Cache.Insert(key,value) Вставляет элемент в кэш под указанным ключевым именем, используя приоритет и время существования по умолчанию. Это эквивалентно применению синтаксиса коллекции на основе индекса и присваиванию нового ключевого имени
Cache.Insert(key, value,dependencies) Вставляет элемент в кэш под указанным ключевым именем, используя приоритет и время существования по умолчанию. Последний параметр содержит объект CacheDependency, связанный с другими файлами или кэшируемыми элементами и позволяющий объявлять данный элемент недействительным в случае их изменения
Cache.Insert(key, value, dependencies, absoluteExpiration, slidingExpiration) Вставляет элемент в кэш под указанным ключевым именем, используя приоритет и указанную политику устаревания (одну из двух). Эта версия метода Insert () используется наиболее часто
Cache.Insert(key, value, dependencies,absoluteExpiration, slidingExpiration, priority, onRemoveCallback) Позволяет конфигурировать все аспекты политики кэширования элемента, включая время существования, зависимости и приоритет. Вдобавок можно передать делегат, указывающий на метод, который должен быть вызван при удалении элемента из кэша

Если выбрано абсолютное устаревание, установите параметр slidingExpiration в TimeSpan.Zero.
Чтобы указать политику скользящего устаревания, установите параметр absoluteExpiration в DateTime.Max.

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

Для получение всех ключей объекта Cache можно воспользоваться перечисление коллекции с использованием класса DictionaryEntry.

Кэширование с помощью элементов управления источниками данных

Все элементы — SqlDataSource, ObjectDataSource и XmlDataSource — поддерживают встроенное кэширование данных.

Для поддержки кэширования все элементы управления источниками данных применяют одни и те же свойства, которые перечислены в табл.

Свойство Описание
EnableCaching Если равно true, то кэширование включено. Значением по умолчанию является false
CacheExpirationPolicy Использует значения из перечисления DataSourceCacheExpiry: Absolute — для абсолютного устаревания (когда указывается фиксированное время нахождение объекта в кэше) или Sliding — для скользящего устаревания (когда временное окно сбрасывается при каждом извлечении объекта из кэша)
CacheDuration Время в секундах нахождения объекта в кэше. Если используется скользящее устаревание, ременной предел сбрасывается каждый раз, когда объект извлекается из кэша. Значение по умолчанию — 0 (или Infinite) — позволяет хранить кэшированные элементы бесконечно
CacheKeyDependency и SqlCacheDependency Позволяет установить зависимость одного кэшированного элемента от другого (CacheKeyDependency) или от таблицы в базе данных (SqlCacheDependency).

Кэширование с помощью SqlDataSource

Когда вы включаете кэширование для элемента управления SqlDataSource, то кэ- шируете результаты Select Query. Однако если вы создаете запрос, принимающий параметры, то SqlDataSource будет кэшировать результаты отдельно для каждого набора значений этих параметров.

Кэширование с помощью ObjectDataSource

Кэширование ObjectDataSource работает с объектом данных, возвращенным SelectMethod. Если вы применяете параметризованный запрос, то ObjectDataSource делает различие между запросами с разными значениями параметров и кэширует их отдельно. К сожалению, кэширование ObjectDataSource обладает существенным ограничением — оно работает только тогда, когда метод выборки возвращает DataSet или DataTable. При возврате объекта любого другого типа возникает исключение NotSupportedException.

Зависимости кэша

С течением времени источники данных могут изменяться в ответ на некоторые действия. Однако если в коде применяется кэширование, вы можете оставаться в неведении об этих изменениях и продолжать использовать устаревшую информацию из кэша. Чтобы помочь в решении этой проблемы, ASP .NET поддерживает зависимости кэша. Эти зависимости позволяют сделать кэшированный элемент зависимым от другого ресурса, так что когда этот ресурс изменится, то кэшированный элемент будет автоматически удален.

Зависимости от файлов и элементов кэша

Чтобы создать зависимость кэша, необходимо построить объект CacheDependency и затем использовать его при добавлении зависимого кэшированного элемента. Например, в следующем коде создается кэшированный элемент, который будет автоматически удален из кэша при изменении, удалении или перезаписи XML -файла:

Если установить зависимость CacheDependency на папку, она будет отслеживать добавление, удаление и модификацию любого файла в этой папке. Модификация вложенной папки (например, переименование, создание или удаление) также нарушает зависимость. Однако более глубокие изменения в дереве каталогов (вроде добавления файла во Сложенную папку или создания вложенной папки второго уровня) не имеют никакого эффекта.

Еще один конструктор принимает массив имен файлов и массив ключей кэша. В следующем примере этот конструктор используется для создания элемента, который зависит от другого элемента в кэше:

Если после этого элемент Cache [«Keyl»] изменится или будет удален из кэша, элемент Cache [«Keyl»] удалится автоматически.

Агрегатные зависимости

Класс AggregateCacheDependency может группировать любое количество объектов CacheDependency. Все, что необходимо сделать — добавить необходимые объекты CacheDependency в массив с применением метода AggregateCacheDependency.Add(). Ниже приведен пример, в котором кэшированный элемент зависит от двух файлов:

Метод обратного вызова при удалении элемента

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

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

DependencyChanged Удален, поскольку зависимость от файла и ключа изменилась
Expired Удален по причине устаревания (в соответствии с его политикой абсолютного или скользящего устаревания)
Removed Удален программно вызовом метода Remove либо метода Insert с тем же ключом
Underused Удален, поскольку среда ASP .NET приняла решение, что объект не достаточно важен, а требуется освободить память

Уведомления кэша SQL

Как работают уведомления кэша

С помощью Service Broker можно принимать уведомления об определенных событиях базы данных. Наиболее прямой подход заключается в применении команды CREATE EVENT NOTIFICATION для указания события, которое необходимо наблюдать. Однако .NET предлагает высокоуровневую модель, интегрированную с ADO.NET. Используя эту модель, вы просто регистрируете команду запроса, a .NET автоматически инструктирует SQL Server о необходимости отправки уведомлений о любых операциях, которые могут повлиять на результат этого запроса. ASP .NET предлагает даже еще более высокоуровневую модель, построенную на этой инфраструктуре и позволяющую автоматически объявить недействительными кэшированные элементы, когда становится недействительным запрос.

Мониторинг изменений в базе данных SQL Server

Включение уведомлений

Единственный конфигурационный шаг, который должен быть выполнен — установка для базы данных флага ENABLEBROKER. Это можно сделать, запустив следующий код SQL (предполагая, что используется база данных Northwind):

Уведомления работают с запросами SELECT и хранимыми процедурами. Однако на синтаксис SELECT накладываются некоторые ограничения. Чтобы правильно поддерживать уведомления, команда должна отвечать следующим требованиям.

Кэшируйте данные на диске веб-сервера. Не кэшируйте соединение БД в объектах Application или Session

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

Насколько безопасны статические переменные?

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

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

E.G Вот пример того, что я делаю:

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

Говорят, что статические переменные и методы, как правило, являются плохими идеями в приложениях, это неверно. Это плохая идея, если вы не знаете, как правильно их использовать, или если вы не знаете, как синхронизировать доступ к ним, если вам нужно, чтобы это выполнялось из параллельных потоков. Написание потокобезопасного кода — очень сложный вопрос, и если у вас есть опасения ошибиться (кто не пишет многопоточные приложения, такие как приложение ASP.NET?) Просто не разделяет это состояние. Используйте хорошо установленные места для этого в приложении ASP.NET:

  • Backend (может быть, например, реляционная база данных)
  • Состояние приложения
  • Контекстное состояние Http
  • Состояние сеанса
  • Файлы cookie клиента

Эти места специально предназначены для хранения состояния в приложении ASP.NET(кроме первого, конечно, который может быть использован в любом типе приложения).


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

Публикуемый ниже материал представляет собой первый совет из целой серии советов по оптимизации приложений, использующих технологии ASP и Visual Basic Scripting Edition (VBScript). Большинство из них были многократно обсуждены и c успехом проверены на веб-сайте Microsoft Corporation и других ASP-сайтах. Авторы материала подразумевают, что вы уже знакомы с основами разработки ASP-приложений, включая VBScript и/или JScript, ASP-сессиями и др. важными объектами (Request, Response и Server).

Кэшируйте часто используемые данные на сервере

Типичная ASP-страница получает данные из базы данных и затем выводит их в формате HTML. Независимо от скорости вашей базы данных, получение данных из памяти сервера намного быстрее, чем обработка sql-запроса к конечной базе данных. Получение данных, сохраненных на локальном жестком диске, также обычно быстрее, чем получение информации из БД. Поэтому одним из основных путей увеличения скорости работы вашей ASP-страницы является кэширование часто используемой информации в памяти или на жестком диске.

Кэширование данных — это классический компромисс «место или время». Если вы избрали для кэширования правильный материал, вы можете видеть внушительное повышение производительности вашего приложения. Чтобы кэширование было эффективным нужно использовать для временного хранения только те данные, которые многократно используются для вывода и каждый раз трудоемки для повторных вычислений. Кэш, полный устаревшей информации, будет пустой тратой памяти сервера.

Данные, которые не изменяются часто, являются хорошим кандидатом для кэширования, потому что вам не надо будет волноваться относительно их синхронизации через какое-то время с конечной базой данных. Выпадающие списки (сombo-box), таблицы ссылок, пункты меню, и переменные конфигурации сайта (включая имена DSN, адреса IP и URL) — первые кандидаты для хранения в кэше. Заметьте, что вы можете кэшировать представление данных много быстрее, нежели данные сами себя. Если ASP-страница изменяется не так часто и ее временный кэш будет весьма внушительным (например, полный каталог изделий фирмы), попробуйте использовать сгенерированные HTML-страницы, чем каждый раз загружать сервер генерацией ASP-страниц.

Кэшируйте часто используемые данные в объектах Application или Session

Объекты Application и Session служат для хранения данных в памяти, значения которых могут быть доступны между несколькими HTTP-запросами (в отличие от обычных переменных, чьи значения доступны только в теле одной ASP-страницы). Данные объекта Session доступны только одному пользователю (в течении его сессии), в то время как данные Application доступны всем пользователям веб-сайта. Поэтому часто перед разработчиком возникает вопрос: в каком из объектов сохранять часто используемые данные. Обычно, для инициализации переменных этих объектов используются процедуры файла Global.asa — Application_OnStart() или Session_OnStart() соответственно. Если в вашем Global.asa еще нет этих процедур, то вы можете добавить их сами или инициализировать переменные, когда это будет необходимо. Примером может быть следующая процедура, использующая Application для хранения значений многократно использующейся переменной EmploymentStatusList. Процедура проверяет существование данных в EmploymentStatusList и при необходимости расчитывает их заново:

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

Function FetchEmploymentStatusList Dim rs Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status Получить все строки FetchEmploymentStatusList = rs.GetRows() rs.Close Set rs = Nothing End Function

Если полученный массив будет часто использоваться, тогда лучше хранить его сразу в виде HTML-списка, чем массив, которое каждый раз нужно преобразовывать в HTML:

Function FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status & vbCrLf rs.Close Set rs = Nothing FetchEmploymentStatusList = s End Function

Кэшируйте данные на диске веб-сервера

Иногда в памяти вашего веб-сервера может быть слишком большое количество данных. «Слишком много», конечно, является спорным вопросом — это зависит от того, сколько памяти вы хотите использовать, а также число элементов для кэширования и частота, с которой эти элементы будут запрашиваться. В любом случае, если вы имеете слишком большое количество данных для кэширования в памяти, подумайте о переносе кэша в текстовый или XML-файл на жесткий диск веб-сервера. Вы можете одновременно комбинировать кэширование на диске и в памяти, чтобы сформировать оптимальную стратегию для вашего сайта.

Заметьте, что при измерении производительности одиночной ASP-страницы, получение данных с диска может не всегда быть быстрее, чем получение равноценных данных из БД. Но «файловое» кэширование уменьшает загрузку БД и сети, а при высокой загрузке БД до, значительно улучшит общую производительность после. Кэширование может быть очень эффективно при кэшировании результатов сложных запросов (например, соединение таблиц), трудоемких процедур сохранения, больших наборов записей. Чтобы убедится, насколько выгодным будет это решение требуется протестировать различные схемы сохранения.

ASP и COM обеспечивают несколько инструментальных средств для создания схем кэширования на диске. Функции набора записей ADO Save() и Open() сохраняют и загружают recordset c диска. Используя эти методы вы можете переписать код из прошлого совета, заменяя запись в объект Application на метод Save() для записи в файл.

Есть несколько других компонентов, которые работают с файлами:

* Scripting.FileSystemObject позволяет создавать, читать и записывать файл.
* MSXML, MicrosoftR XML parser поддерживает сохранение и загрузку XML-документов.
* Объект LookupTable (например, используемый на MSN.com) — лучший выбор для загрузки простых списков с диска.

Наконец, рассмотрите вопрос принудительного кэширования информации на диске. Сгенерированный HTML-код может быть сохранен на диске как.htm или.asp файл; гиперссылки могут указывать прямо на этот файл. Вы можете автоматизировать процесс генерации HTML, используя коммерческие инструментальные средства типа XBuilder или средства публикации в Интернет, входящие в MicrosoftR SQL ServerT. Кроме того, при помощи директивы #include можно включать отдельные HTML-части в файл ASP или читать HTML-файл с диска используя FileSystemObject. Например, на начальной странице vbCode (http://vbcity.com/vbcode/ru/home.asp) приводятся 10 последних тем обсуждения двух дискуссионных форумов. Отобразить эти списки можно при помощи создания двух наборов записей ADO при каждом обращении к данной странице или, следуя данному совету, сохранить их однажды в виде HTML-файла list.inc, а затем включать в home.asp:

Второй путь работает значительно быстрее.

Избегайте кэшировать медленные компоненты в объектах Application или Session

Несмотря на то, что кэшированиe данных в объектах Application или Session может быть хорошей идеей, кэширование COM-объектов может иметь серьезные ловушки. Занесение наиболее используемых COM-объектов в объекты Application или Session часто соблазняет, но, к сожалению, много COM-объектов, включая все, написанные в Visual Basic 6.0 или ранее, могут вызывать серьезные критические проблемы после сохранения в объектах Application или Session.

В частности, любой компонент, который выполняется медленно, вызовет критические проблемы когда кэшируется в объектах Session или Application. Быстрый (проворный non-agile) компонент — компонент, помеченный ThreadingModel=Both, который объединен Free-threaded marshaler (FTM), или — компонент, помеченный ThreadingModel=Neutral. (Neutral — новая модель в WindowsR 2000 and COM+). Следующие компоненты не проворны:

* Free-threaded components.
* Apartment-threaded components.
* Single-threaded component.
* Configured components (библиотека Microsoft Transaction Server (MTS)/COM+ и серверные приложения) не проворны пока они Neutral-threaded. Apartment-threaded components и другие не проворные компоненты хорошо работают в пределах страницы (т.е. создаются и разрушаются в пределах одной ASP-страницы).

В IIS 4.0 компонент, отмеченный ThreadingModel=Both выполняется быстро. В IIS 5.0 уже не так достаточно. Компонент не должен только быть отмечен как Both, он должен также объединен FTM.

IIS выполняет проверку компонентов, но если вы хотите ее отменить (т.е. хотите позволить непроворным компонентам быть сохраненными в объектах Application или Session), вы можете установить AspTrackThreadingModel в metabase в значение True. Но это (изменение AspTrackThreadingModel) не рекомендуется.

IIS 5.0 выдаст сообщение об ошибке, если Вы пытаетесь сохранить непроворный компонент, созданный с использованием Server.CreateObject, в объекте Application. Вы можете обойти это, используя в Global.asa, но это также не рекомендуется, поскольку это ведет к проблемам (очереди и сериализация), объясняемым ниже.

Что же все-таки неправильно если вы кэшируете непроворные компоненты? Непроворный компонент, кэшируемый в объекте Session блокирует Session от других рабочих потоков (thread) ASP. ASP обслуживает пул (контейнер) рабочих потоков, запрашиваемых другими сервисами. Обычно, новый запрос обрабатывается первым доступным потоком. Если Session блокирована, то запрос должен ждать поток, когда он станет доступным. Проведем аналогию, которая поможет понять эту ситуацию: вы идете в магазин, выбираете несколько булок, и платите за них в кассе #3. Всякий раз, после того как вы выбрали булки в том магазине, вы всегда оплачиваете их в кассе #3, даже в том случае, когда в других кассах короче очередь или даже вообще нет покупателей.

Сохранение непроворных компонентов в объект Application накладывает столь же негативный эффект на производительность. ASP создает специальный поток для выполнения меделенных компонентов в пределах Application. Это имеет два последствия: все запросы выстраиваются в очередь к этому потоку и все запросы сериализуются. Выстраивание в очередь означает, что параметры были сохранены в общедоступной области памяти; запросы переключаются к специальному потоку; метод компонента выполнен; результаты выстраиваются в общедоступную область. Сериализация (преобразование в последовательную форму) означает, что все методы выполняются в одно время. Для двух различных потоков ASP не возможно одновременное выполнение методов общедоступного компонента. Это уничтожает многопотоковость (параллелизм), особенно на мультипроцессорных системах. Хуже всего то, что все непроворные компоненты в пределах Application совместно используют один поток («Host STA»), так что негативные результаты сериализации налицо.

Смущены? Есть некоторые общие правила. Если Вы пишете объекты в Visual Basic (6.0 или ранее), не храните их в объектах Application или Session. Если вы не знаете потоковую модель объекта, не храните его в кэше. Вместо кэширования где-либо непроворных объектов, вы должны создать и удалить их на каждой странице. Объекты выполнятся непосредственно в рабочем потоке ASP и не будет никакой очереди или сериализации. Производимость будет адекватна, если COM-объекты запущены под IIS и если они не используют много времени, чтобы инициализироваться и уничтожаться. Заметьте, что однопотоковые (single-threaded) объекты не должны использоваться этот путь. Будьте внимательным — VB может создавать однопотоковые объекты! Если вы используете однопотоковые объекты, этот путь (типа таблицы Microsoft Excel) не рассчитывает на высокую производительность.

Наборы записей (recordset) ADO могут безопасно кэшироваться когда ADO отмечен как Free-threaded. Чтобы сделать ADO как Free-threaded используйте файл Makfre15.bat, который обычно зафиксирован в каталоге Program FilesCommon FilesSystemADO.

Предупреждение: ADO не должен быть Free-threaded, если вы используете Microsoft Access в качестве БД. Набор записей ADO должен быть также вообще отсоединен, если вы не можете управлять конфигурацией ADO на вашем веб-сайте.

Не кэшируйте соединение БД в объектах Application или Session

Кэширование соединений ADO — обычно плохая стратегия. Если один объект Connection сохранен в объекте Application и используется на всех страницах, то все страницы будут бороться за использование этого соединения. Если объект Connection сохранен в ASP-объекте Session, то соединение БД будет создано для каждого пользователя. Это создает излишнюю загрузку веб-сервера и БД.

Вместо кэширования соединений БД, создавайте и уничтожайте объекты ADO на каждой ASP странице, которая использует ADO. Это эффективно, потому что IIS имеет встроенное подключение БД. Более точно, IIS автоматически допускает объединение подключений OLEDB и ODBC. Это гарантирует, что создание и уничтожение связей на каждой странице будут эффективны.

Так как соединенные наборы хранят ссылки на подключение БД, это следует, что вы должны не кэшировать соединенные наборы в объектах Application или Session. Однако, вы можете безопасно кэшировать отсоединенные наборы, которые не держат ссылку на подключение. Чтобы отсоединить набор записей, сделайте следующие два шага:

Set rs = Server.CreateObject(«ADODB.RecordSet») rs.CursorLocation = adUseClient » шаг 1 » Заполните recordset с данными rs.Open strQuery, strProv » Теперь отсоедините recordset от источника данных rs.ActiveConnection = Nothing » шаг 2

Подробную информацию относительно подключений смотрите в справочниках по ADO и SQL Server.

Разумное использование объекта Session

Теперь, когда в предыдущих советах были раскрыты достоинства кэширования данных в объектах Applications и Sessions, мы собираемся предложить вам избегать использования объекта Session. Сессии имеют несколько ловушек когда используются на загруженных сайтах. Под «загруженными» имеются ввиду сайты с сотнями запрашиваемых страниц в секунду или тысячами пользователей одновременно. Этот совет также важен для сайтов, которые должны масштабироваться горизонтально — т.е. те сайты, которые используют несколько серверов для распределения нагрузки и обеспечения отказоустойчивости при сбоях. Для меньших сайтов, типа intranet-сайтов, преимущества применения Sessions все же перевешивают.

Обобщая, ASP автоматически создает Session для каждого пользователя, который обращается к веб-серверу. Каждая сессия занимает приблизительно 10 Кб памяти (сверх любых данных, сохраненных в Session) и немного замедляет выполнение всех запросов. Сессия остается действующей до окончания таймаута (timeout), обычно 20 мин.

Но самая большая проблема при использовании сессий — это не производительность, а расширяемость. Сессии не охватывают все задействованные веб-сервера; как только Session была создана на одном сервере ее данные остаются там. Это означает, что если вы используете сессии на мультисерверном веб-сайте, вы должны придумать стратегию для обработки запросов каждого пользователя, которые должны быть всегда направлены на сервер, на котором существует сессия этого пользователя. Это называется «застреванием» пользователя на сервере (или «липкой сессией»).

Объект Application также не охватывает все сервера: если вам нужно совместно использовать и обновлять данные Application через веб-сервера, вам нужно использовать конечную базу данных. Однако неизменяемые (read-only) данные Application все же полезны на мультисерверных сайтах.

Наиболее критичные к скорости сайты обычно используют не менее двух веб-серверов. Поэтому при проектировании вашего ASP-приложения вы должны либо использовать «липкие сессии», либо просто избегать применения объекта Session, также как любых других методов, сохраняющих информацию пользователя на разных веб-серверах.

Если же вы не используете Session, то убедитесь, что отключили их. Это можно сделать посредством Internet Services Manager (см. документацию по ISM). Но если вам все-таки необходимо использовать сессии, то есть несколько путей уменьшить их удары про производительности.

Вы можете переместить содержимое, которое не требует сессий (например, страницы help и т.д.) в отдельное ASP-приложение, у которого сессии выключены. Кроме того, на страницах, где объект Session не используется, применяйте следующую директиву, помещещаемую вверху страницы:

Одна из основных причин ее применения — то, что Session создает интересную проблему в случае использования фрэймов (frameset). ASP гарантирует, что в любое время будет выполняться только один запрос от Session. Это делается для того, чтобы при одновременном запросе одним пользователем нескольких страниц, только один ASP-запрос был обработан сессией, что помогает избежать проблем многопоточного доступа к объекту Session. К сожалению, в результате этого все страницы в frameset будут загружаться последовательно, а не одновременно, и пользователю придется продолжительное время ждать полной загрузки. Мораль этой истории: если вы не уверены, что с использованием фрэймов и Session ваше приложение правильно работает, то используйте:

Альтернативой использованию объекта Session являются многочисленные параметры управления Session. При передаче малых объемов данных (менее 4 Кб) обычно рекомендуется использовать Cookies, переменные QueryString и скрытые (hidden) переменные форм. При использовании большого количества передаваемых параметров (например, корзина произведенных заказов в он-лайн магазине) наиболее лучший выбор — конечная база данных.

Статья будет полезна как новичкам, так и профессионалам. Первые получат сведения об основных возможностях MySQL, без чтения документации. А уже имея представление о…

A thread is defined as the execution path of a program. Each thread defines a unique flow of control. If your application involves complicated and time consuming operations such as database access or some intense I/O operations, then it is often helpful to set different execution paths or threads, with each thread performing a particular job.

Threads are lightweight processes. One common example of use of thread is implementation of concurrent programming by modern operating systems. Use of threads saves wastage of CPU cycle and increases efficiency of an application.

So far we compiled programs where a single thread runs as a single process which is the running instance of the application. However, this way the application can perform one job at a time. To make it execute multiple tasks at a time, it could be divided into smaller threads.

In .Net, the threading is handled through the «System.Threading» namespace. Creating a variable of the System.Threading.Thread type allows you to create a new thread to start working with. It allows you to create and access individual threads in a program.

Creating Thread

A thread is created by creating a Thread object, giving its constructor a ThreadStart reference.

ThreadStart childthreat = new ThreadStart(childthreadcall);

Thread Life Cycle

The life cycle of a thread starts when an object of the System.Threading.Thread class is created and ends when the thread is terminated or completes execution.

Following are the various states in the life cycle of a thread:

The Unstarted State : It is the situation when the instance of the thread is created but the Start method is not called.

The Ready State : It is the situation when the thread is ready to execute and waiting CPU cycle.

The Not Runnable State : a thread is not runnable, when:

  • Sleep method has been called
  • Wait method has been called
  • Blocked by I/O operations

The Dead State : It is the situation when the thread has completed execution or has been aborted.

Thread Priority

The Priority property of the Thread class specifies the priority of one thread with respect to other. The .Net runtime selects the ready thread with the highest priority.

The priorities could be categorized as:

  • Above normal
  • Below normal
  • Highest
  • Lowest
  • Normal

Once a thread is created, its priority is set using the Priority property of the thread class.

Thread Properties & Methods


The Thread class has the following important properties:

Property Description
CurrentContext Gets the current context in which the thread is executing.
CurrentCulture Gets or sets the culture for the current thread.
CurrentPrinciple Gets or sets the thread»s current principal for role-based security.
CurrentThread Gets the currently running thread.
CurrentUICulture Gets or sets the current culture used by the Resource Manager to look up culture-specific resources at run time.
ExecutionContext Gets an ExecutionContext object that contains information about the various contexts of the current thread.
IsAlive Gets a value indicating the execution status of the current thread.
IsBackground Gets or sets a value indicating whether or not a thread is a background thread.
IsThreadPoolThread Gets a value indicating whether or not a thread belongs to the managed thread pool.
ManagedThreadId Gets a unique identifier for the current managed thread.
Name Gets or sets the name of the thread.
Priority Gets or sets a value indicating the scheduling priority of a thread.
ThreadState Gets a value containing the states of the current thread.

The Thread class has the following important methods:

Полезные советы по оптимизации ASP-приложений. Кэшируйте часто используемые данные в объектах Application или Session

A few years back Phil Haack wrote a great article on the dangers of recurring background tasks in ASP.NET . In it he points out a few gotchas that are SO common when folks try to do work in the background. Read it, but here»s a summary from his post.

  • An unhandled exception in a thread not associated with a request will take down the process.
  • If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time.
  • The AppDomain your site runs in can go down for a number of reasons and take down your background task with it.

If you think you can just write a background task yourself, it»s likely you»ll get it wrong. I»m not impugning your skills, I»m just saying it»s subtle . Plus, why should you have to?

There»s LOT of great ways for you to do things in the background and a lot of libraries and choices available.

Some ASP.NET apps will be hosted in IIS in your data center and others will be hosted in the Azure cloud. The spectrum of usage is roughly this, in my opinion:

  • General: Hangfire (or similar similar open source libraries)
    • used for writing background tasks in your ASP.NET website
  • Cloud:
    • A formal Azure feature used for offloading running of background tasks outside of your Website and scale the workload
  • Advanced: Azure Worker Role in a Cloud Service
    • scale the background processing workload independently of your Website and you need control over the machine

There»s lots of great articles and videos on how to use , and lots of documentation on how Worker Roles in scalable Azure Cloud Services work, but not a lot about how your hosted ASP.NET application and easily have a background service. Here»s a few.

WebBackgrounder

As it says «WebBackgrounder is a proof-of-concept of a web-farm friendly background task manager meant to just work with a vanilla ASP.NET web application.» Its code hasn»t been touched in years, BUT the WebBackgrounder NuGet package has been downloaded almost a half-million times.

The goal of this project is to handle one task only, manage a recurring task on an interval in the background for a web app.

If your ASP.NET application just needs one background task to runs an a basic scheduled interval, than perhaps you just need the basics of WebBackgrounder.

Using System;
using System.Threading;
using System.Threading.Tasks;

namespace WebBackgrounder.DemoWeb
<
public class SampleJob: Job
<
public SampleJob(TimeSpan interval, TimeSpan timeout)
: base(«Sample Job», interval, timeout)
<
>

Public override Task Execute()
<
return new Task(() => Thread.Sleep(3000));
>
>
>

Built in: QueueBackgroundWorkItem — Added in .NET 4.5.2

Somewhat in response to the need for WebBackgrounder, .NET 4.5.2 added QueueBackgroundWorkItem as a new API . It»s not just a «Task.Run,» it tries to be more:

QBWI schedules a task which can run in the background, independent of any request. This differs from a normal ThreadPool work item in that ASP.NET automatically keeps track of how many work items registered through this API are currently running, and the ASP.NET runtime will try to delay AppDomain shutdown until these work items have finished executing.

It can try to delay an AppDomain for as long as 90 seconds in order to allow your task to complete. If you can»t finish in 90 seconds, then you»ll need a different (and more robust, meaning, out of process) technique.

The API is pretty straightforward, taking Func . Here»s an example that kicks of a background work item from an MVC action:

Public ActionResult SendEmail( User user)
<
if (ModelState.IsValid)
<
HostingEnvironment.QueueBackgroundWorkItem(ct => SendMailAsync(user.Email));
return RedirectToAction(«Index», «Home»);
>

FluentScheduler

FluentScheduler is a more sophisticated and complex scheduler that features a (you guessed it) fluent interface. You have really explicit control over when your tasks run.

public class MyRegistry: Registry
<
public MyRegistry()
<
// Schedule an ITask to run at an interval
Schedule ().ToRunNow().AndEvery(2).Seconds();

// Schedule a simple task to run at a specific time
Schedule(() => Console.WriteLine(«Timed Task — Will run every day at 9:15pm: » + DateTime.Now)).ToRunEvery(1).Days().At(21, 15);

// Schedule a more complex action to run immediately and on an monthly interval
Schedule(() =>
<
Console.WriteLine(«Complex Action Task Starts: » + DateTime.Now);
Thread.Sleep(1000);
Console.WriteLine(«Complex Action Task Ends: » + DateTime.Now);
>).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
>
>

FluentScheduler also embraces IoC and can easily plug into your favorite Dependency Injection tool of choice by just implementing their ITaskFactory interface.

Quartz.NET

Quartz.NET is a .NET port of the popular Java job scheduling framework of the (almost) same name. It»s very actively developed. Quartz has an IJob interface with just one method, Execute, to implement.

Using Quartz;
using Quartz.Impl;
using System;

namespace ScheduledTaskExample.ScheduledTasks
<
public class JobScheduler
<
public static void Start()
<
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();

IJobDetail job = JobBuilder.Create ().Build();

ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
.Build();

Then, inside your Application_Start, you call JobScheduler.Start(). There»s a great getting started article on Quartz at Mikesdotnetting you should check out.

Hangfire

And last but definitely not least, the most polished (IMHO) of the group,

Об опасностях выполнения фоновых задач в ASP.NET. Он выделил три основных риска, связанных с запуском фонового процесса:

  1. Необработанное исключение в потоке, несвязанном с запросом, может снять процесс.
  2. Если запустить сайт в веб-ферме, то есть вероятность случайно завершить несколько экземпляров приложения, которое могло запустить несколько экземпляров одной и той же задачи одновременно.
  3. Домен приложения, в котором запущен сайт, по разным причинам может выгрузиться и снять фоновую задачу, запущенную в нем.

Конечно, можно написать собственный менеджер для управления фоновыми задачами. Но, вероятнее всего, Вы сделаете это неправильно. Никто не собирается оспаривать Ваши навыки разработчика. Просто создание подобного менеджера — это достаточно тонкая вещь. Да и зачем Вам это надо?

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

Какие-то ASP.NET приложения могут работать на Ваших собственных серверах под IIS, какие-то размещаться в Azure.

Для запуска фоновых задач можно выделить несколько вариантов:

HANGFIRE

Документация Hangfire действительно превосходна. Хотелось бы, чтобы каждый проект с открытым исходным кодом имел такую документацию.

Одной из самых эффектных функций Hangfire является встроенная аналитическая панель, которая позволяет просматривать расписания, выполняющиеся задания, успешные и неуспешно завершенные задания.

Hangfire позволяет легко определить задачи типа «запустить и забыть», информация о которых будет храниться в базе данных:

BackgroundJob.Enqueue(() => Console.WriteLine(«Fire-and-forget»));
Можно отсрочить выполнение задачи:

BackgroundJob.Schedule(() => Console.WriteLine(«Delayed»), TimeSpan.FromDays(1));
Или запустить задачу в CRON стиле

RecurringJob.AddOrUpdate(() => Console.Write(«Recurring»), Cron.Daily);
Работать с Hangfire очень удобно. Hangfire имеет хорошую документацию и обучающие руководства , основанные на реальных примерах.

Hangfire — это целая экосистема для работы с фоновыми задачами в ASP.NET приложениях.

Библиотеки доступны в виде открытых исходных кодов или Nuget пакетов.

Итоги (лично от себя)

Я уже знаю, что мне нужно запускать больше одного процесса, и работать процессы могут долго (ограничение в 90 секунд на завершение в QueueBackgroundWorkItem). FluentScheduler выглядит неплохо, но хотелось большего. Hangfire – отличное решение, но, вроде, сразу требует использования базы данных для хранения очереди задач. Да и не совсем там все бесплатно – есть и платная версия.

В итоге я пока выбрал Quartz.NET: вполне приличная документация, достаточное количество примеров, чтобы быстро начать использовать, а также расширяемый функционал, который можно добавлять по мере возрастания потребностей.

Если вы знаете другие библиотеки для запуска фоновых задач или имеете опыт решения подобных задач – делитесь в комментариях.

АККОМПАНИРОВАТЬ accompagner ,> нем. akkompanieren . 1 . дипл. Приложить к чему-л., спроводить чем-л. (какую-л . посылку, отправление) . Я тот экстракт письмом своим не аккомпанировал. Кантемир Реляц. 2 172.

2. расш. Сопровождать кого-, что-л., быть дополнением к чему-л. Спинат, растение самое здоровое и для всякого желудка годное.. аккомпанирует все нарядные блюда. 1809. Гримо Прихотник 60. Однажды меня с Сазоновым (он мне всегда аккомпанирует в Ватикане) заперли. Гальберг Письма 57. Одни злословят по привычке, другие аккомпанируют. Ростопчин Ох, французы 114. Дежурный по полку ротмистр доказал, что ему хотелось есть и что аппетит у него богатырский, да и мы все аккомпанировали ему недурно, нечего сказать, не отказываясь от лафита и д»икема, которым, гостеприимный хозяин наполнял наши стаканы. В. П. Бурнашев Восп. // РА 1872 1839.

3. 1690. Лексис. муз. Сопровождать аккомпанементом. Акомпанировать своему голосу . Кн. муз. 52. Играть соло или аккомпанировать в сих концертах. Финдейз. 171. <Отец> играл на Виолончеле, и всегда акомпанировал наши Дуо. ММ 3 14. Он же Куликов фортепианами и арфою аккомпанирует. <Шарманщик> аккомпанирует вальс Ланнера свистками и трелями. Григорович Петерб. шарманщик. Он аккомпанировал Вьетану и многим певцам. Римский-Корс. Летопись. // РР 1970 1 60. || Припевать, подпевать . Но не было ли, спрашивает он, в вашем пении монотонии? Было, отвечает целомудренная супруга; но в финале все хорошо акомпанировали. Зритель 1 121. Хватайко поет и все акомпанируют: бери, большой тут нет науки. Капнист Ябеда 85.

4. перен. Сопровождая что-л., создавать определенный фон. БАС-2. Шепот продолжался, и ему аккомпанировал смущенно-счастливый смех. Мам.- Сиб. Черты из жизни Пепко. Собаки, смирно лежавшие у ворот, не выдерживали <визга поросят> и принялись аккомпанировать громким лаем и воем. А. Осипович Мечтатели. // ОЗ 1881 8 1 462. Лишь папа лесничий Дрожжинин шумно ел суточные щи, да мама для этикета аккомпанировала, едва разжимая строгие губы. Аксенов Затоварен. бочкотара. // РР 1970 3 60. — Лекс. Ян.1803: акомпанировать; Соколов 1834: акомпаниров а/ ть; Даль: акомпаниров а/ ть; САН 1933: аккомпан и/ ровать; Сл. 18: аккомпанировать 1734 (ако- 1792).

Исторический словарь галлицизмов русского языка. — М.: Словарное издательство ЭТС http://www.ets.ru/pg/r/dict/gall_dict.htm . Николай Иванович Епишкин [email protected] . 2010 .


Смотреть что такое «аккомпанировать» в других словарях:

АККОМПАНИРОВАТЬ — (фр. accompagner). Сопровождать пение игрою на каком либо музыкальном инструменте. Словарь иностранных слов, вошедших в состав русского языка. Чудинов А.Н., 1910. АККОМПАНИРОВАТЬ франц. accompagner. Сопровождать пение игрою на каком либо… … Словарь иностранных слов русского языка

аккомпанировать — См … Словарь синонимов

аккомпанировать — и устарелое аккомпанировать … Словарь трудностей произношения и ударения в современном русском языке

АККОМПАНИРОВАТЬ — АККОМПАНИРОВАТЬ, рую, руешь; несовер., кому. Исполнять аккомпанемент. А. на рояле. Толковый словарь Ожегова. С.И. Ожегов, Н.Ю. Шведова. 1949 1992 … Толковый словарь Ожегова

АККОМПАНИРОВАТЬ — кого или что (сонату) чем, на чем, муз., франц. вторить, сопровождать, подголашивать, подголосить, подыгрывать; держать другой, согласный голос. Аккомпанирование ср., ·длит. аккомпанировка жен., ·об. действие по гл., вторенье, подголоска,… … Толковый словарь Даля

аккомпанировать — (иноск. шут.) вторить, делать что в подражание другому, совместно с ним (намек на сопровождение пения или одного инструмента игрою одного или многих инструментов) Ср. Я издавна солист и аккомпанемента не ожидаю, один пью. Лесков. На ножах. 1,… … Большой толково-фразеологический словарь Михельсона

Аккомпанировать — несов. неперех. 1. Сопровождать игрой на музыкальном инструменте или на музыкальных инструментах сольную вокальную или инструментальную партию, основную тему или мелодию музыкального произведения. 2. перен. Создавать определённый фон, сопровождая … Современный толковый словарь русского языка Ефремовой

аккомпанировать — аккомпанировать, аккомпанирую, аккомпанируем, аккомпанируешь, аккомпанируете, аккомпанирует, аккомпанируют, аккомпанируя, аккомпанировал, аккомпанировала, аккомпанировало, аккомпанировали, аккомпанируй, аккомпанируйте, аккомпанирующий,… … Формы слов

аккомпанировать — аккомпан ировать, рую, рует … Русский орфографический словарь

аккомпанировать — (I), аккомпани/рую, руешь, руют … Орфографический словарь русского языка

Книги

  • Учись аккомпанировать на 6-струнной гитаре. От романсов к року и джазу , Манилов В.. В книге вы найдете необходимые сведения об аккордах, их последовательностях и способах усложнения партии ритм-гитары, о стандартной аппликатуре и типовых ритмических моделях различных жанров…

Последнее обновление: 10.03.2020

Одним из ключевых нововведений последних версий фреймворка.NET стала асинхронность. Хотя фреймворк и раньше позволял использовать асинхронные методы, но с появлением библиотеки Task Parallel Library работа с асинхронным кодом была предельно упрощена, а сам формат работы изменился. Были добавлены новые возможности по созданию асинхронных методов с использованием новых ключевых слов, таких как async и await.

При создании нового контроллера мы в настройках уже можем указать, как нам нужен контроллер — синхронный или асинхронный. По умолчанию Visual Studio добавляет в проект стандартные контроллеры, методы которых, как правило, возвращают объект ActionResult. Но если мы при добавлении контроллера в папку Controllers выберем тип MVC 5 Controller with views, using Entity Framework , то в окне настройки нового контроллера специальное поле позволит нам указать, что новый контроллер будет содержать асинхронные методы:

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

Чтобы понять различие между синхронными и асинхронными методами, рассмотрим, как IIS обрабатывает входящие запросы. Веб-сервер поддерживает пул потоков, которые обслуживают запросы. При обращении пользователя к веб-ресурсу IIS выделяет поток из пула для обслуживания данного запроса. И пока данный поток не обработает предназначенный для него запрос, другие запросы он обрабатывать не может.

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

И если обработка запроса блокируется очень долго, то IIS начинает задействовать для обслуживания других входящих запросов новые потоки. Однако есть ограничения на общее количество потоков. Когда количество потоков достигает предела, то вновь входящие запросы помещаются в очередь ожидания. Однако и тут есть ограничение на количество запросов в очереди. И когда это количество превышает предел, то IIS просто отклоняет все остальные запросы с помощью статусного кода 503 (Service Unavailable).

При асинхронной обработке поток не ждет, пока БД вернет ему данные, а начинает обрабатывать запрос от другого пользователя. Но когда, наконец, с сетевого ресурса или БД придут нужные данные, поток возвращается к обработке ранее обрабатываемого запроса в обычном режиме.

Перейдем непосредственно к коду. Для создания асинхронных методов используются модификаторы async и await , которые позволяют выполнять продолжительные операции без блокирования основного потока.

Сравним на примере вызов синхронного и асинхронного метода:

Using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using AsyncContollers.Models; using System.Threading.Tasks; using System.Data.Entity; namespace AsyncContollers.Controllers < public >books = db.Books; ViewBag.Books = books; return View(); > // асинхронный метод public async Task BookList() < IEnumerable books = await db.Books.ToListAsync(); ViewBag.Books = books; return View("Index"); >> >

Оба метода выполняют одну и ту же операцию — извлечение данных из БД и получают идентичные результаты. Но если первый синхронный метод Index представляет привычную для нас запись, то асинхронный метод BookList уже выглядит необычно.

Кроме того, чтобы обозначить метод как асинхронный, перед возвращаемым типом ставится ключевое слово async .

Третьим ключевым моментом является использование ключевого слова await . Оно применяется в асинхронных методах, чтобы приостановить выполнение этого метода до тех пор, пока ожидаемая задача не завершится. В нашем случае такой задачей является получение данных из БД.

Но также следует учитывать, что await используется с методами, возвращающими объект Task . Поэтому для получения данных из БД используется метод await db.Books.ToListAsync() , который также извлекает данные из БД, но уже в асинхронном режиме.

Когда следует использовать асинхронные методы? В первую очередь их предпочтительно использовать при запросах к БД, к внешнем сетевым ресурсам, однако в конечном счете, что лучше синхронность или асинхронность решает уже сам разработчик исходя из конкретной задачи.

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

Публикуемый ниже материал представляет собой первый совет из целой серии советов по оптимизации приложений, использующих технологии ASP и Visual Basic Scripting Edition (VBScript). Большинство из них были многократно обсуждены и c успехом проверены на веб-сайте Microsoft Corporation и других ASP-сайтах. Авторы материала подразумевают, что вы уже знакомы с основами разработки ASP-приложений, включая VBScript и/или JScript, ASP-сессиями и др. важными объектами (Request, Response и Server).

Кэшируйте часто используемые данные на сервере

Типичная ASP-страница получает данные из базы данных и затем выводит их в формате HTML. Независимо от скорости вашей базы данных, получение данных из памяти сервера намного быстрее, чем обработка sql-запроса к конечной базе данных. Получение данных, сохраненных на локальном жестком диске, также обычно быстрее, чем получение информации из БД. Поэтому одним из основных путей увеличения скорости работы вашей ASP-страницы является кэширование часто используемой информации в памяти или на жестком диске.

Кэширование данных — это классический компромисс «место или время». Если вы избрали для кэширования правильный материал, вы можете видеть внушительное повышение производительности вашего приложения. Чтобы кэширование было эффективным нужно использовать для временного хранения только те данные, которые многократно используются для вывода и каждый раз трудоемки для повторных вычислений. Кэш, полный устаревшей информации, будет пустой тратой памяти сервера.

Данные, которые не изменяются часто, являются хорошим кандидатом для кэширования, потому что вам не надо будет волноваться относительно их синхронизации через какое-то время с конечной базой данных. Выпадающие списки (сombo-box), таблицы ссылок, пункты меню, и переменные конфигурации сайта (включая имена DSN, адреса IP и URL) — первые кандидаты для хранения в кэше. Заметьте, что вы можете кэшировать представление данных много быстрее, нежели данные сами себя. Если ASP-страница изменяется не так часто и ее временный кэш будет весьма внушительным (например, полный каталог изделий фирмы), попробуйте использовать сгенерированные HTML-страницы, чем каждый раз загружать сервер генерацией ASP-страниц.

Кэшируйте часто используемые данные в объектах Application или Session

Объекты Application и Session служат для хранения данных в памяти, значения которых могут быть доступны между несколькими HTTP-запросами (в отличие от обычных переменных, чьи значения доступны только в теле одной ASP-страницы). Данные объекта Session доступны только одному пользователю (в течении его сессии), в то время как данные Application доступны всем пользователям веб-сайта. Поэтому часто перед разработчиком возникает вопрос: в каком из объектов сохранять часто используемые данные. Обычно, для инициализации переменных этих объектов используются процедуры файла Global.asa — Application_OnStart() или Session_OnStart() соответственно. Если в вашем Global.asa еще нет этих процедур, то вы можете добавить их сами или инициализировать переменные, когда это будет необходимо. Примером может быть следующая процедура, использующая Application для хранения значений многократно использующейся переменной EmploymentStatusList. Процедура проверяет существование данных в EmploymentStatusList и при необходимости расчитывает их заново:

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

Function FetchEmploymentStatusList Dim rs Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status Получить все строки FetchEmploymentStatusList = rs.GetRows() rs.Close Set rs = Nothing End Function

Если полученный массив будет часто использоваться, тогда лучше хранить его сразу в виде HTML-списка, чем массив, которое каждый раз нужно преобразовывать в HTML:

Function FetchEmploymentStatusList Dim rs, fldName, s Set rs = CreateObject(«ADODB.Recordset») rs.Open «select StatusName, Status & vbCrLf rs.Close Set rs = Nothing FetchEmploymentStatusList = s End Function

Кэшируйте данные на диске веб-сервера

Иногда в памяти вашего веб-сервера может быть слишком большое количество данных. «Слишком много», конечно, является спорным вопросом — это зависит от того, сколько памяти вы хотите использовать, а также число элементов для кэширования и частота, с которой эти элементы будут запрашиваться. В любом случае, если вы имеете слишком большое количество данных для кэширования в памяти, подумайте о переносе кэша в текстовый или XML-файл на жесткий диск веб-сервера. Вы можете одновременно комбинировать кэширование на диске и в памяти, чтобы сформировать оптимальную стратегию для вашего сайта.

Заметьте, что при измерении производительности одиночной ASP-страницы, получение данных с диска может не всегда быть быстрее, чем получение равноценных данных из БД. Но «файловое» кэширование уменьшает загрузку БД и сети, а при высокой загрузке БД до, значительно улучшит общую производительность после. Кэширование может быть очень эффективно при кэшировании результатов сложных запросов (например, соединение таблиц), трудоемких процедур сохранения, больших наборов записей. Чтобы убедится, насколько выгодным будет это решение требуется протестировать различные схемы сохранения.

ASP и COM обеспечивают несколько инструментальных средств для создания схем кэширования на диске. Функции набора записей ADO Save() и Open() сохраняют и загружают recordset c диска. Используя эти методы вы можете переписать код из прошлого совета, заменяя запись в объект Application на метод Save() для записи в файл.

Есть несколько других компонентов, которые работают с файлами:

* Scripting.FileSystemObject позволяет создавать, читать и записывать файл.
* MSXML, MicrosoftR XML parser поддерживает сохранение и загрузку XML-документов.
* Объект LookupTable (например, используемый на MSN.com) — лучший выбор для загрузки простых списков с диска.

Наконец, рассмотрите вопрос принудительного кэширования информации на диске. Сгенерированный HTML-код может быть сохранен на диске как.htm или.asp файл; гиперссылки могут указывать прямо на этот файл. Вы можете автоматизировать процесс генерации HTML, используя коммерческие инструментальные средства типа XBuilder или средства публикации в Интернет, входящие в MicrosoftR SQL ServerT. Кроме того, при помощи директивы #include можно включать отдельные HTML-части в файл ASP или читать HTML-файл с диска используя FileSystemObject. Например, на начальной странице vbCode (http://vbcity.com/vbcode/ru/home.asp) приводятся 10 последних тем обсуждения двух дискуссионных форумов. Отобразить эти списки можно при помощи создания двух наборов записей ADO при каждом обращении к данной странице или, следуя данному совету, сохранить их однажды в виде HTML-файла list.inc, а затем включать в home.asp:

Второй путь работает значительно быстрее.

Избегайте кэшировать медленные компоненты в объектах Application или Session

Несмотря на то, что кэшированиe данных в объектах Application или Session может быть хорошей идеей, кэширование COM-объектов может иметь серьезные ловушки. Занесение наиболее используемых COM-объектов в объекты Application или Session часто соблазняет, но, к сожалению, много COM-объектов, включая все, написанные в Visual Basic 6.0 или ранее, могут вызывать серьезные критические проблемы после сохранения в объектах Application или Session.

В частности, любой компонент, который выполняется медленно, вызовет критические проблемы когда кэшируется в объектах Session или Application. Быстрый (проворный non-agile) компонент — компонент, помеченный ThreadingModel=Both, который объединен Free-threaded marshaler (FTM), или — компонент, помеченный ThreadingModel=Neutral. (Neutral — новая модель в WindowsR 2000 and COM+). Следующие компоненты не проворны:

* Free-threaded components.
* Apartment-threaded components.
* Single-threaded component.
* Configured components (библиотека Microsoft Transaction Server (MTS)/COM+ и серверные приложения) не проворны пока они Neutral-threaded. Apartment-threaded components и другие не проворные компоненты хорошо работают в пределах страницы (т.е. создаются и разрушаются в пределах одной ASP-страницы).

В IIS 4.0 компонент, отмеченный ThreadingModel=Both выполняется быстро. В IIS 5.0 уже не так достаточно. Компонент не должен только быть отмечен как Both, он должен также объединен FTM.

IIS выполняет проверку компонентов, но если вы хотите ее отменить (т.е. хотите позволить непроворным компонентам быть сохраненными в объектах Application или Session), вы можете установить AspTrackThreadingModel в metabase в значение True. Но это (изменение AspTrackThreadingModel) не рекомендуется.

IIS 5.0 выдаст сообщение об ошибке, если Вы пытаетесь сохранить непроворный компонент, созданный с использованием Server.CreateObject, в объекте Application. Вы можете обойти это, используя в Global.asa, но это также не рекомендуется, поскольку это ведет к проблемам (очереди и сериализация), объясняемым ниже.

Что же все-таки неправильно если вы кэшируете непроворные компоненты? Непроворный компонент, кэшируемый в объекте Session блокирует Session от других рабочих потоков (thread) ASP. ASP обслуживает пул (контейнер) рабочих потоков, запрашиваемых другими сервисами. Обычно, новый запрос обрабатывается первым доступным потоком. Если Session блокирована, то запрос должен ждать поток, когда он станет доступным. Проведем аналогию, которая поможет понять эту ситуацию: вы идете в магазин, выбираете несколько булок, и платите за них в кассе #3. Всякий раз, после того как вы выбрали булки в том магазине, вы всегда оплачиваете их в кассе #3, даже в том случае, когда в других кассах короче очередь или даже вообще нет покупателей.

Сохранение непроворных компонентов в объект Application накладывает столь же негативный эффект на производительность. ASP создает специальный поток для выполнения меделенных компонентов в пределах Application. Это имеет два последствия: все запросы выстраиваются в очередь к этому потоку и все запросы сериализуются. Выстраивание в очередь означает, что параметры были сохранены в общедоступной области памяти; запросы переключаются к специальному потоку; метод компонента выполнен; результаты выстраиваются в общедоступную область. Сериализация (преобразование в последовательную форму) означает, что все методы выполняются в одно время. Для двух различных потоков ASP не возможно одновременное выполнение методов общедоступного компонента. Это уничтожает многопотоковость (параллелизм), особенно на мультипроцессорных системах. Хуже всего то, что все непроворные компоненты в пределах Application совместно используют один поток («Host STA»), так что негативные результаты сериализации налицо.

Смущены? Есть некоторые общие правила. Если Вы пишете объекты в Visual Basic (6.0 или ранее), не храните их в объектах Application или Session. Если вы не знаете потоковую модель объекта, не храните его в кэше. Вместо кэширования где-либо непроворных объектов, вы должны создать и удалить их на каждой странице. Объекты выполнятся непосредственно в рабочем потоке ASP и не будет никакой очереди или сериализации. Производимость будет адекватна, если COM-объекты запущены под IIS и если они не используют много времени, чтобы инициализироваться и уничтожаться. Заметьте, что однопотоковые (single-threaded) объекты не должны использоваться этот путь. Будьте внимательным — VB может создавать однопотоковые объекты! Если вы используете однопотоковые объекты, этот путь (типа таблицы Microsoft Excel) не рассчитывает на высокую производительность.

Наборы записей (recordset) ADO могут безопасно кэшироваться когда ADO отмечен как Free-threaded. Чтобы сделать ADO как Free-threaded используйте файл Makfre15.bat, который обычно зафиксирован в каталоге Program FilesCommon FilesSystemADO.

Предупреждение: ADO не должен быть Free-threaded, если вы используете Microsoft Access в качестве БД. Набор записей ADO должен быть также вообще отсоединен, если вы не можете управлять конфигурацией ADO на вашем веб-сайте.

Не кэшируйте соединение БД в объектах Application или Session

Кэширование соединений ADO — обычно плохая стратегия. Если один объект Connection сохранен в объекте Application и используется на всех страницах, то все страницы будут бороться за использование этого соединения. Если объект Connection сохранен в ASP-объекте Session, то соединение БД будет создано для каждого пользователя. Это создает излишнюю загрузку веб-сервера и БД.

Вместо кэширования соединений БД, создавайте и уничтожайте объекты ADO на каждой ASP странице, которая использует ADO. Это эффективно, потому что IIS имеет встроенное подключение БД. Более точно, IIS автоматически допускает объединение подключений OLEDB и ODBC. Это гарантирует, что создание и уничтожение связей на каждой странице будут эффективны.

Так как соединенные наборы хранят ссылки на подключение БД, это следует, что вы должны не кэшировать соединенные наборы в объектах Application или Session. Однако, вы можете безопасно кэшировать отсоединенные наборы, которые не держат ссылку на подключение. Чтобы отсоединить набор записей, сделайте следующие два шага:

Set rs = Server.CreateObject(«ADODB.RecordSet») rs.CursorLocation = adUseClient » шаг 1 » Заполните recordset с данными rs.Open strQuery, strProv » Теперь отсоедините recordset от источника данных rs.ActiveConnection = Nothing » шаг 2

Подробную информацию относительно подключений смотрите в справочниках по ADO и SQL Server.

Разумное использование объекта Session

Теперь, когда в предыдущих советах были раскрыты достоинства кэширования данных в объектах Applications и Sessions, мы собираемся предложить вам избегать использования объекта Session. Сессии имеют несколько ловушек когда используются на загруженных сайтах. Под «загруженными» имеются ввиду сайты с сотнями запрашиваемых страниц в секунду или тысячами пользователей одновременно. Этот совет также важен для сайтов, которые должны масштабироваться горизонтально — т.е. те сайты, которые используют несколько серверов для распределения нагрузки и обеспечения отказоустойчивости при сбоях. Для меньших сайтов, типа intranet-сайтов, преимущества применения Sessions все же перевешивают.

Обобщая, ASP автоматически создает Session для каждого пользователя, который обращается к веб-серверу. Каждая сессия занимает приблизительно 10 Кб памяти (сверх любых данных, сохраненных в Session) и немного замедляет выполнение всех запросов. Сессия остается действующей до окончания таймаута (timeout), обычно 20 мин.

Но самая большая проблема при использовании сессий — это не производительность, а расширяемость. Сессии не охватывают все задействованные веб-сервера; как только Session была создана на одном сервере ее данные остаются там. Это означает, что если вы используете сессии на мультисерверном веб-сайте, вы должны придумать стратегию для обработки запросов каждого пользователя, которые должны быть всегда направлены на сервер, на котором существует сессия этого пользователя. Это называется «застреванием» пользователя на сервере (или «липкой сессией»).

Объект Application также не охватывает все сервера: если вам нужно совместно использовать и обновлять данные Application через веб-сервера, вам нужно использовать конечную базу данных. Однако неизменяемые (read-only) данные Application все же полезны на мультисерверных сайтах.

Наиболее критичные к скорости сайты обычно используют не менее двух веб-серверов. Поэтому при проектировании вашего ASP-приложения вы должны либо использовать «липкие сессии», либо просто избегать применения объекта Session, также как любых других методов, сохраняющих информацию пользователя на разных веб-серверах.

Если же вы не используете Session, то убедитесь, что отключили их. Это можно сделать посредством Internet Services Manager (см. документацию по ISM). Но если вам все-таки необходимо использовать сессии, то есть несколько путей уменьшить их удары про производительности.

Вы можете переместить содержимое, которое не требует сессий (например, страницы help и т.д.) в отдельное ASP-приложение, у которого сессии выключены. Кроме того, на страницах, где объект Session не используется, применяйте следующую директиву, помещещаемую вверху страницы:

Одна из основных причин ее применения — то, что Session создает интересную проблему в случае использования фрэймов (frameset). ASP гарантирует, что в любое время будет выполняться только один запрос от Session. Это делается для того, чтобы при одновременном запросе одним пользователем нескольких страниц, только один ASP-запрос был обработан сессией, что помогает избежать проблем многопоточного доступа к объекту Session. К сожалению, в результате этого все страницы в frameset будут загружаться последовательно, а не одновременно, и пользователю придется продолжительное время ждать полной загрузки. Мораль этой истории: если вы не уверены, что с использованием фрэймов и Session ваше приложение правильно работает, то используйте:

Альтернативой использованию объекта Session являются многочисленные параметры управления Session. При передаче малых объемов данных (менее 4 Кб) обычно рекомендуется использовать Cookies, переменные QueryString и скрытые (hidden) переменные форм. При использовании большого количества передаваемых параметров (например, корзина произведенных заказов в он-лайн магазине) наиболее лучший выбор — конечная база данных.

Статья будет полезна как новичкам, так и профессионалам. Первые получат сведения об основных возможностях MySQL, без чтения документации. А уже имея представление о…

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL