Re[11]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.03.05 02:58
Оценка:
Здравствуйте, IT, Вы писали:

IT>И как я понимаю, для агрегированных значений тоже генерируется вызов Dispose, если они его поддерживают? А если у меня агрегированный объект is object or ArrayList?


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

Но вообще-то ПК прав. Интеграция реализации паттернов в язык — это правильно. Чем меньше нужно думать, тем лучше. Все эти навороты по реализации диспоза отнюдь не радуют. Радует, только то что их крайне редко приходится реализовывать вручную. А использование упрощается юсингом (тоже, кстати, встроенная поддержка паттерна).
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 19.03.05 03:20
Оценка:
VladD2,

> IT> И как я понимаю, для агрегированных значений тоже генерируется вызов Dispose, если они его поддерживают? А если у меня агрегированный объект is object or ArrayList?


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


Так делать нельзя: Object нельзя хранить "по значению", следовательно остается только ссылка/указатель. В этом случае никакой уверенности, что класс, содержащий ссылку, является владельцем объекта, нет. Так можно запросто разрушить чужие данные.

> Все эти навороты по реализации диспоза отнюдь не радуют. Радует, только то что их крайне редко приходится реализовывать вручную.


Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.

Другая проблема — сохранение инвариантов при возникновении исключений. Т.к. в C# на уровне языка поддержки для автоматизации транзакций нет (худо-бедно, но обеспечиваемой в C++ деструкторами), в итоге после "неожиданного" исключения программа легко может просто перестать работать. Она обычно не вылетает, но и правильно не работает. Вот такие пироги...
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Будущее С++/CLI
От: Хитрик Денис Россия RSDN
Дата: 19.03.05 10:21
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.


Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?
Правила нашего с вами форума.
Как правильно задавать вопросы. © 2001 by Eric S. Raymond; перевод: © 2002 Валерий Кравчук.
Re[9]: Будущее С++/CLI
От: Юнусов Булат Россия  
Дата: 19.03.05 17:00
Оценка: 4 (1)
Здравствуйте, Павел Кузнецов, Вы писали:

Токмо для наглядности

http://weblogs.asp.net/cnagel/archive/2005/01/23/359037.aspx
Re[10]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 19.03.05 17:42
Оценка:
Булат,

> Токмо для наглядности

> http://weblogs.asp.net/cnagel/archive/2005/01/23/359037.aspx

Там есть существенная неточность в отношении Dispose и Finalize применительно к C++/CLI:

The Dispose(bool) pattern still must be done.


В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.03.05 19:01
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

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


ПК>Так делать нельзя:...


Пашь, ну, хоть чуть-чуть юмора то нужно иметь.

ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.


У вас случаем на работе фины не работают? Полтора дня искать такую ошибку — это достойно книги гинеса.

ПК>Другая проблема — сохранение инвариантов при возникновении исключений. Т.к. в C# на уровне языка поддержки для автоматизации транзакций нет (худо-бедно, но обеспечиваемой в C++ деструкторами), в итоге после "неожиданного" исключения программа легко может просто перестать работать. Она обычно не вылетает, но и правильно не работает. Вот такие пироги...


Пошь, это уже просто клинический случай предвзятости. Если бы все было как ты описывашь, то все по прежнему писали бы на плюсах и никто на шарп даже не взглянул.
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.03.05 19:01
Оценка:
Здравствуйте, Хитрик Денис, Вы писали:

ХД>Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?


Дуамаю это проблемы ментолитета. Когда человек 10 лет вынужден был особождать ресурсы, то даже будучи освобожденным от этого он по привычке продолжает строить свой код подобным образом.

В общем, пора писать статью "Жизть после того как память перестала быть ресурсом".
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 19.03.05 19:36
Оценка:
VladD2,

> ХД> Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?


> Дуамаю это проблемы ментолитета. Когда человек 10 лет вынужден был особождать ресурсы, то даже будучи освобожденным от этого он по привычке продолжает строить свой код подобным образом. В общем, пора писать статью "Жизть после того как память перестала быть ресурсом".


LOL. Один из людей, о которых идет речь, к "плюсам" уже как минимум несколько лет не прикасался, пожалуй, за исключением чтения и мелких правок, и в языках, с которыми он в основном работает, управлять памятью не приходится и близко. Просто (естественно) хочется сделать так, чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[11]: Будущее С++/CLI
От: Юнусов Булат Россия  
Дата: 19.03.05 19:38
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Там есть существенная неточность в отношении Dispose и Finalize применительно к C++/CLI:

ПК>

ПК>The Dispose(bool) pattern still must be done.


ПК>В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.


Хорошо, если так.
Re[16]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.05 01:52
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>LOL. Один из людей, о которых идет речь, к "плюсам" уже как минимум несколько лет не прикасался, пожалуй, за исключением чтения и мелких правок, и в языках, с которыми он в основном работает, управлять памятью не приходится и близко. Просто (естественно) хочется сделать так, чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную.


После плюсов слова "чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную" звучат как издевательство. Я тут как раз воюю с Синтиловским кодом...
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.05 01:52
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.


Слабо в это верится. Всегда можно втупую привести объект к IDispose и вызвать метод.
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[17]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 20.03.05 03:17
Оценка:
VladD2,

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


Видимо, авторы "Синтиловского кода" "плюсы" готовить не умеют.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[12]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 20.03.05 03:23
Оценка:
VladD2,

> ПК> В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.


> Слабо в это верится. Всегда можно втупую привести объект к IDispose и вызвать метод.


В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[18]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.05 03:50
Оценка: :)
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Видимо, авторы "Синтиловского кода" "плюсы" готовить не умеют.


А их умею готовить только гуры и то в примерах. А в раельном где большого проекта всегда попадается подобная фигня:
void ScintillaWin::Paste() {
    if (!::OpenClipboard(MainHWND()))
        return;
    pdoc->BeginUndoAction();
    int selStart = SelectionStart();
    ClearSelection();
    bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;

    // Always use CF_UNICODETEXT if available
    HGLOBAL hmemUSelection = ::GetClipboardData(CF_UNICODETEXT);
    if (hmemUSelection) {
        wchar_t *uptr = static_cast<wchar_t *>(::GlobalLock(hmemUSelection));
        if (uptr) {
            unsigned int len;
            XCHAR *putf;
            // Default Scintilla behaviour in Unicode mode
            if (IsUnicodeMode()) {
                unsigned int bytes = ::GlobalSize(hmemUSelection);
                len = UTF8Length(uptr, bytes / 2);
                putf = new XCHAR[len + 1];
                if (putf) {
                    UTF8FromUCS2(uptr, bytes / 2, putf, len);
                }
            } else {
                // CF_UNICODETEXT available, but not in Unicode mode
                // Convert from Unicode to current Scintilla code page
                UINT cpDest = CodePageFromCharSet(
                    vs.styles[STYLE_DEFAULT].characterSet, pdoc->dbcsCodePage);
                len = ::WideCharToMultiByte(cpDest, 0, uptr, -1,
                                            NULL, 0, NULL, NULL) - 1; // subtract 0 terminator
                putf = new XCHAR[len + 1];
                if (putf) {
                    //::WideCharToMultiByte(cpDest, 0, uptr, -1,
                    //                      putf, len + 1, NULL, NULL);
                    WCharToXChar(cpDest, uptr, len + 1, putf);
                }
            }

            if (putf) {
                if (isRectangular) {
                    PasteRectangular(selStart, putf, len);
                } else {
                    if (pdoc->InsertString(currentPos, putf, len)) {
                        SetEmptySelection(currentPos + len);
                    }
                }
                delete []putf;
            }
        }
        ::GlobalUnlock(hmemUSelection);
    } else {
        // CF_UNICODETEXT not available, paste ANSI text
        HGLOBAL hmemSelection = ::GetClipboardData(CF_TEXT);
        if (hmemSelection) {
            XCHAR *ptr = static_cast<XCHAR *>(
                            ::GlobalLock(hmemSelection));
            if (ptr) {
                unsigned int bytes = ::GlobalSize(hmemSelection);
                unsigned int len = bytes;
                for (unsigned int i = 0; i < bytes; i++) {
                    if ((len == bytes) && (0 == ptr[i]))
                        len = i;
                }

                // In Unicode mode, convert clipboard text to UTF-8
                if (IsUnicodeMode()) {
                    wchar_t *uptr = static_cast<wchar_t *>(::GlobalAlloc(GPTR,
                                                           len * 2 + 2));

                    //unsigned int ulen = ::MultiByteToWideChar(CP_ACP, 0,
                    //                    ptr, len, uptr, GlobalSize(static_cast<wchar_t *>(uptr)));
                    unsigned int ulen = XCharToWChar(CP_ACP, ptr, len, uptr, GlobalSize(static_cast<wchar_t *>(uptr)));

                    unsigned int mlen = UTF8Length(uptr, ulen);
                    XCHAR *putf = new XCHAR[mlen + 1];
                    if (putf) {
                        // CP_UTF8 not available on Windows 95, so use UTF8FromUCS2()
                        UTF8FromUCS2(uptr, ulen, putf, mlen);
                    }

                    ::GlobalFree(static_cast<wchar_t *>(uptr));

                    if (isRectangular) {
                        PasteRectangular(selStart, putf, mlen);
                    } else {
                        pdoc->InsertString(currentPos, putf, mlen);
                        SetEmptySelection(currentPos + mlen);
                    }
                    delete []putf;
                } else {
                    if (isRectangular) {
                        PasteRectangular(selStart, ptr, len);
                    } else {
                        pdoc->InsertString(currentPos, ptr, len);
                        SetEmptySelection(currentPos + len);
                    }
                }
            }
            ::GlobalUnlock(hmemSelection);
        }
    }
    ::CloseClipboard();
    pdoc->EndUndoAction();
    NotifyChange();
    Redraw();
}
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Будущее С++/CLI
От: VladD2 Российская Империя www.nemerle.org
Дата: 20.03.05 03:50
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.


Ну, тогда напиши друзьям занимающимся реализацией этой спецификации, что у них ничего не получилось:
System::IO::StreamReader reader("C:\\boot.ini");
IDisposable ^ disposable = dynamic_cast<IDisposable^>(%reader);

disposable->~IDisposable();

Console::WriteLine(reader.ReadToEnd());

... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 20.03.05 05:49
Оценка: :))
VladD2,

> ПК> В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.


> Ну, тогда напиши друзьям занимающимся реализацией этой спецификации, что у них ничего не получилось: <...>


См. выделенное выше. Это еще не вошло в билд, который есть у тебя. Но спецификация еще может измениться. И не раз
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[19]: Будущее С++/CLI
От: Cyberax Марс  
Дата: 20.03.05 09:06
Оценка: +1 :)
VladD2 пишет:

> ПК>Видимо, авторы "Синтиловского кода" "плюсы" готовить не умеют.

> А их умею готовить только гуры и то в примерах. А в раельном где
> большого проекта всегда попадается подобная фигня:

А давайте ее чуть-чуть перепишем:
void ScintillaWin::Paste() {
    if (!::OpenClipboard(MainHWND()))
        return;
    ON_BLOCK_EXIT(CloseClipboard,MainHWND());

    pdoc->BeginUndoAction();
    ON_BLOCK_EXIT_OBJ(*pdoc,ScintillaDocument::EndUndoAction);

    int selStart = SelectionStart();
    ClearSelection();
    bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;

    // Always use CF_UNICODETEXT if available
    HGLOBAL hmemUSelection = ::GetClipboardData(CF_UNICODETEXT);

    if (hmemUSelection) {
        wchar_t *uptr = static_cast<wchar_t 
*>(::GlobalLock(hmemUSelection));
        ON_BLOCK_EXIT(::GlobalUnlock,hmemUSelection);

        if (uptr) {
            unsigned int len;
            std::wstring putf;
           
            unsigned int bytes = ::GlobalSize(hmemUSelection);
            putf=std::wstring(uptr,bytes/sizeof(wchar_t));

            // Default Scintilla behaviour in Unicode mode
            if (IsUnicodeMode()) {
                if (isRectangular) {
                    PasteRectangular(selStart, putf.c_str(), len);
                } else {
                    if (pdoc->InsertString(currentPos, putf.c_str(), len)) {
                        SetEmptySelection(currentPos + len);
                    }
                }               
            } else {
                // CF_UNICODETEXT available, but not in Unicode mode
                // Convert from Unicode to current Scintilla code page
                std::string converted=convert_from_unicode(putf,
                    pdoc->dbcsCodePage);
                if (isRectangular) {
                    PasteRectangular(selStart, converted.c_str(), len);
                } else {
                    if (pdoc->InsertString(currentPos, 
converted.c_str(), len)) {
                        SetEmptySelection(currentPos + len);
                    }
                }
            }

        }   
    } else {
        //I'm bored with it
    }
    NotifyChange();
    Redraw();
}

У меня тут наверняка куча ошибок, но если нормально писать на
современном С++, то код будет выглядеть примерно как у меня.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[9]: Будущее С++/CLI
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.03.05 11:12
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Торможу. Видимо, смутило использование слова "реализует": для меня это означает какие-то действия по предоставлению реализаций функций, определенных в интерфейсе — с C# мало общаюсь Ладно, это лирика.


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

ПК>Да, добавление деструктора в ref class добавляет в список базовых интерфейсов неявное наследование от System::IDisposable


Реализацию

ПК>, если его там еще нет. Плюс, если класс унаследован от System::IDisposable


Реализует

ПК>Т.е., скажем, при наследовании от IEnumerable,


Реализации

ПК> который в свою очередь унаследован от IDisposable


А вот здесь правильно.

Это касательно терминологии. Теперь касательно сути — ни в 1.1 ни в 2.0 IEnumerable от IDisposable не наследуется.
... << RSDN@Home 1.1.4 beta 4 rev. 365>>
AVK Blog
Re[13]: Будущее С++/CLI
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.03.05 11:15
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.


WeekReference спасет ваших отцов русской демократии
... << RSDN@Home 1.1.4 beta 4 rev. 365>>
AVK Blog
Re[10]: Будущее С++/CLI
От: Павел Кузнецов  
Дата: 20.03.05 18:31
Оценка:
AndrewVK,

> Привыкай к терминологии В нете интерфейс это отдельная сущность, а не абстрактный класс, как в плюсах. Поэтому класс не наследует интерфейс, а реализует


Это в C#. В C++/CLI взаимозаменяемо используют "наследует" и "реализует". Более того, в C++/CLI интерфейс CLI называется интерфейсным классом

> и, имхо, это правильно, поскольку наследование реализаций и интерфейсов вещи вобщем то концептуально различные.


Далеко не всегда хочется разделять наследование от ref класса и от interface класса. Например:
template< typename T >
ref class C : public T
{
   . . .
};

здесь в качестве T может быть как ref class, так и interface class (а в будущем — и просто class), и все время мучиться выговаривая "базовый ref класс или реализуемый интерфейс" никакой выгоды, по-моему, не дает. А в будущем еще и придется все эти места поправить, добавив "или класс". В общем, я пока не вижу большого смысла в постоянном подчеркивании различия между наследованием от ref class, interface class и class.

> Теперь касательно сути — ни в 1.1 ни в 2.0 IEnumerable от IDisposable не наследуется.


Не расширяет?

Видимо, ошибочка в примере вышла. С другой стороны, для сути совершенно неважно, какой именно интерфейс был бы приведен в качестве примера — это не суть, а несущественная деталь. Можно взять IEnumerator<T>, который таки наследуется от (расширяет ?) IDisposable. Суть-то не в том, что облегчается реализация классов, реализующих (экая тавтология получается ) IEnumerable, а в том, что облегчается реализация классов, (возможно косвенно) наследующих (так в данном случае, имхо, звучит приятнее ) IDisposable.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.