Ошибка проверки схемы / Потокобезопасность XmlSchemaSet?

Посмотрите, я нашел этот Стиль Передачи Продолжения лучшее описание по этой теме.

Здесь лишен копии деталей той статьи:

Автор: Дата 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 могут использоваться для хранения состояния вычисления, которое должно быть возобновлено после того, как данные возвращаются. Со сложными случаями, например, когда данные используются функцией, которая должна возвратить некоторое значение его вызывающей стороне, продолжения значительно упрощают вещи. Вы просто регистрируете продолжение как обратный вызов, и Ваше вычисление возобновляется, когда запрос заканчивается.

5
задан Filipe Toscano 28 September 2009 в 12:23
поделиться

2 ответа

У меня была та же проблема. Похоже, что проверка XML - это не операция только для чтения, на что указывает эта статья:

http://blogs.msdn.com/xmlteam/archive/2009/04/27/xmlschemaset-thread-safety.aspx

Установка замка решила для меня проблему.

1
ответ дан 14 December 2019 в 08:55
поделиться
  1. Вы описываете результат контролируемого эксперимента или наблюдение из производственной среды? Если последнее, попробуйте воспроизвести его в управляемой настройке, чтобы убедиться, что какая-то другая ошибка не является реальной причиной.

  2. В документации для XmlSchemaSet говорится:

    «Потокобезопасность любых членов экземпляра не гарантируется».

    Это включает чтение свойств и методы «только для чтения». {{1} } Таким образом, мы не можем предположить, что использование XmlSchemaSet только для чтения будет потокобезопасным. Пока Microsoft не предоставит реализацию, которая явно разрешает совместное использование одного и того же скомпилированного представления схемы между потоками, единственное, что можно сделать, это не делиться.

  3. OTOH кажется логичным использовать один скомпилированный неизменяемый XmlSchemaSet для проверки нескольких XmlDocument (или XmlReader ) экземпляров. {{1} } Это очень разумный сценарий, поэтому я не понимаю, почему он явно не разрешен и не задокументирован.

    (Обновление: очевидно, это явно гарантируется в стандартной XML-библиотеке Java . Почему этого не происходит в .NET?)

4
ответ дан 14 December 2019 в 08:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: