StreamWriter & ldquo; Использование & rdquo; Синтаксис для C ++ / CLI - правильное закрытие файла при неожиданном сбое [дубликат]

Вот некоторые подходы к работе с асинхронными запросами:
  1. Объект обезьяны браузера
  2. Q - A
  3. A + Promises.js
  4. jQuery отложен
  5. API XMLHttpRequest
  6. Использование концепции обратного вызова - как реализация в первом ответе

Пример: jQuery отложенная реализация для работы с несколькими запросами

var App = App || {};

App = {
    getDataFromServer: function(){

      var self = this,
                 deferred = $.Deferred(),
                 requests = [];

      requests.push($.getJSON('request/ajax/url/1'));
      requests.push($.getJSON('request/ajax/url/2'));

      $.when.apply(jQuery, requests).done(function(xhrResponse) {
        return deferred.resolve(xhrResponse.result);
      });
      return deferred;
    },

    init: function(){

        this.getDataFromServer().done(_.bind(function(resp1, resp2) {

           // Do the operations which you wanted to do when you
           // get a response from Ajax, for example, log response.
        }, this));
    }
};
App.init();
0
задан user1173240 3 June 2015 в 09:04
поделиться

1 ответ

C ++ / CLI не имеет эквивалента , используя ключевое слово . Для этого потребовался другой подход, который ожидают программисты на C ++. Кто знаком с очень распространенной идиомой C ++ для реализации детерминированного уничтожения, RAII-шаблона . Вызов этого требует использования «семантики стека». Хорошо работает, требования синтаксиса, однако, довольно неясны.

Сначала я покажу неуклюжий способ, полезный для демонстрации различий синтаксиса. Позволяет использовать StreamReader, одноразовый класс в .NET:

String^ ReadTopLineFromFile(String^ path) {
    StreamReader^ reader = gcnew StreamReader(path);
    try {
        return reader->ReadLine();
    }
    finally {
        delete reader;
    }
}

Try / наконец-то делает код исключительным-безопасным, если ReadLine () генерирует исключение, тогда объект StreamReader все еще расположен, и блокировка файла гарантированно будет выпущена. Это код, который компилятор C # автоматически испускает, когда вы используете оператор using. Также обратите внимание на использование оператора delete, он фактически вызывает метод StreamReader :: Dispose (). Компилятор не позволит вам писать reader->Dispose(), использование оператора является обязательным.

Теперь с использованием версии, которую поддерживает компилятор C ++ / CLI. Вы вызываете семантику стека, эмулируя способ, которым нативный компилятор C ++ рассматривает объект C ++, выделенный в стеке. Например:

String^ ReadTopLineFromFile(String^ path) {
    StreamReader reader(path);
    return reader.ReadLine();
}   // <== disposed here

Обратите внимание на недостающую ^ шляпу на имя переменной, обычно требуемую, когда она хранит ссылку ссылочного типа. Умышленное исключение - это то, что вызывает шаблон. Никакого явного вызова gcnew не требуется, компилятор автоматически испускает его. Также обратите внимание, что вы больше не используете -> для разыменования объекта, теперь вы используете .

Компилятор C ++ / CLI автоматически генерирует блоки try / finally, а также вызов оператора delete. Который испускается при закрывающей скобке блока видимости. Так же, как и собственный компилятор C ++. Хотя выглядит , как управляемый объект выделяется в стеке, это всего лишь синтаксическая иллюзия, он все еще находится в куче GC.

Синтаксис очень отличается, конечно, единственное реальное зависание с функцией. Знание того, когда использовать ^ шляпу и когда полагаться на семантику стека, - это то, что нужно изучить, занимает некоторое время.

8
ответ дан Hans Passant 25 August 2018 в 17:45
поделиться
Другие вопросы по тегам:

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