Посмотрите, я нашел этот Стиль Передачи Продолжения лучшее описание по этой теме.
Здесь лишен копии деталей той статьи:
Автор: Дата Marijn Haverbeke: 24-го июля 2007
функция вызова функции на контексте выполнения программы Схемы позволяет получить вычисление, состояние стека вызовов, как это было, и возобновляют то же самое состояние в более позднее время. Вдобавок к такой примитивной, различной форме обработки исключений и подобного C longjmp могут быть реализованы приемы.
function traverseDocument(node, func) { func(node); var children = node.childNodes; for (var i = 0; i < children.length; i++) traverseDocument(children[i], func); } function capitaliseText(node) { if (node.nodeType == 3) // A text node node.nodeValue = node.nodeValue.toUpperCase(); } traverseDocument(document.body, capitaliseText);
Это может быть преобразовано следующим образом: Мы добавляем дополнительный аргумент каждой функции, которая будет использоваться для передачи продолжения функции. Это продолжение является значением функции, представляющим действия, которые должны произойти после функции 'возвраты'. (Вызов) стек становится устаревшим в передающем продолжение стиле †• когда вызовы функции другая функция, которая является последней вещью, которую она делает. Вместо того, чтобы ожидать вызванной функции для возврата это помещает любую работу, которую это хочет сделать впоследствии в продолжение, которое это передает функции.
function traverseDocument(node, func, c) { var children = node.childNodes; function handleChildren(i, c) { if (i < children.length) traverseDocument(children[i], func, function(){handleChildren(i + 1, c);}); else c(); } return func(node, function(){handleChildren(0, c);}); } function capitaliseText(node, c) { if (node.nodeType == 3) node.nodeValue = node.nodeValue.toUpperCase(); c(); } traverseDocument(document.body, capitaliseText, function(){});
Предполагают, что у нас есть huuuuge документ для превращения в капитал. Просто пересечение его сразу занимает пять секунд, и замораживание браузера в течение пяти секунд является довольно плохим стилем. Рассмотрите эту простую модификацию capitaliseText (не обращайте внимание на ужасное глобальное):
var nodeCounter = 0; function capitaliseText(node, c) { if (node.nodeType == 3) node.nodeValue = node.nodeValue.toUpperCase(); nodeCounter++; if (nodeCounter % 20 == 0) setTimeout(c, 100); else c(); }
Теперь, каждые двадцать узлов, вычисление прервано, чтобы сто миллисекунд дали интерфейсу браузера момент для ответа на ввод данных пользователем. Очень примитивная форма поточной обработки †• можно даже выполнить множественные вычисления одновременно как это.
А чаще всего полезное приложение этого связано с XMLHttpRequests, или различный IFRAME и взломы ТЕГА SCRIPT раньше моделировали их. Они всегда требуют, чтобы работал с некоторым механизмом обратного вызова для обработки данных, которые передает обратно сервер. В простых случаях тривиальная функция сделает, или несколько globals могут использоваться для хранения состояния вычисления, которое должно быть возобновлено после того, как данные возвращаются. Со сложными случаями, например, когда данные используются функцией, которая должна возвратить некоторое значение его вызывающей стороне, продолжения значительно упрощают вещи. Вы просто регистрируете продолжение как обратный вызов, и Ваше вычисление возобновляется, когда запрос заканчивается.
У меня была та же проблема. Похоже, что проверка XML - это не операция только для чтения, на что указывает эта статья:
http://blogs.msdn.com/xmlteam/archive/2009/04/27/xmlschemaset-thread-safety.aspx
Установка замка решила для меня проблему.
Вы описываете результат контролируемого эксперимента или наблюдение из производственной среды? Если последнее, попробуйте воспроизвести его в управляемой настройке, чтобы убедиться, что какая-то другая ошибка не является реальной причиной.
В документации для XmlSchemaSet
говорится:
«Потокобезопасность любых членов экземпляра не гарантируется».
Это включает чтение свойств и методы «только для чтения». {{1} } Таким образом, мы не можем предположить, что использование XmlSchemaSet
только для чтения будет потокобезопасным.
Пока Microsoft не предоставит реализацию, которая явно разрешает совместное использование одного и того же скомпилированного представления схемы
между потоками, единственное, что можно сделать, это не делиться.
OTOH кажется логичным использовать один скомпилированный неизменяемый XmlSchemaSet
для проверки
нескольких XmlDocument
(или XmlReader
) экземпляров. {{1} } Это очень разумный сценарий, поэтому я не понимаю, почему он явно
не разрешен и не задокументирован.
(Обновление: очевидно, это явно гарантируется в стандартной XML-библиотеке Java . Почему этого не происходит в .NET?)