Действительно ли безопасно назвать RCW от финализатора?

РЕДАКТИРОВАНИЕ: ответ Milhous , кажется, официально поддерживаемый способ сделать это с 10,5. Более ранняя версия OS X и даже 10.5 и должна все еще работать с помощью следующих инструкций все же.

  1. Открываются , командная строка (Терминал)

  2. Перешла к Вашей папке установки Eclipse, например:

    • cd /Applications/eclipse/
    • cd /Developer/Eclipse/Eclipse.app/Contents/MacOS/eclipse
    • cd /Applications/eclipse/Eclipse.app/Contents/MacOS/eclipse
    • cd /Users//eclipse/jee-neon/Eclipse.app/Contents/MacOS
  3. Запуск Eclipse: ./eclipse &

Эта последняя команда запустит затмение и сразу фон процесс.

Промывка и повторение для открытия стольких уникальных экземпляров Eclipse, сколько Вы хотите.

Предупреждение

Вы могли бы иметь к [1 125], изменяют Tomcat порты сервера для выполнения проекта в [1 126] различные/несколько экземпляры Tomcat , уже см. Ошибка Сервера Tomcat - Порт 8080 используемый

17
задан Andrew Arnott 15 October 2009 в 17:57
поделиться

2 ответа

Я узнал от самой команды CLR, что это действительно небезопасно - , если вы не выделите GCHandle на RCW, пока это еще безопасно (когда вы сначала приобретите RCW). Это гарантирует, что сборщик мусора и финализатор не суммировали RCW до того, как управляемый объект, который должен его вызвать, будет завершен.

class MyManagedObject : IDisposable
{
    private ISomeObject comServer;
    private GCHandle rcwHandle;
    private IServiceProvider serviceProvider;
    private uint cookie;

    public MyManagedObject(IServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
        this.comServer = this. serviceProvider.GetService(/*some service*/) as ISomeObject;
        this.rcwHandle = GCHandle.Alloc(this.comServer, GCHandleType.Normal);
        this.cookie = comServer.GetCookie();
    }

    ~MyManagedObject()
    {
        this.Dispose(false);
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // dispose owned managed objects here.
        }

        if (this.rcwHandle.IsAllocated)
        {
            // calling this RCW is safe because we have a GC handle to it.
            this.comServer.ReleaseCookie(this.cookie);

            // Now release the GC handle on the RCW so it can be freed as well
            this.rcwHandle.Free();
        }
    }
}

Оказывается, в моем конкретном случае мое приложение размещает саму среду CLR. Следовательно, он вызывает mscoree! CoEEShutdownCOM перед тем, как поток финализатора запускается, что завершает работу RCW и приводит к ошибке InvalidComObjectException , которую я видел.

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

16
ответ дан 30 November 2019 в 13:27
поделиться

No it is not safe to access a RCW from the finalizer thread. Once you reach the finalizer thread you have no guarantee that the RCW is still alive. It is possible for it to be ahead of your object in the finalizer queue and hence released by the time your destructor runs on the finalizer thread.

7
ответ дан 30 November 2019 в 13:27
поделиться
Другие вопросы по тегам:

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