COM-Interop, EAccessViolation после выхода из приложения - PullRequest
0 голосов
/ 26 мая 2011

У меня проблема с ActiveX, который я использую через COM-Interop.это вызывает исключение после того, как я покидаю свое приложение, и я не уверен, является ли это моей ошибкой или ошибкой ActiveX.

- это правильный способ инициализации и выпуска ActiveX через COM-Interop?

Сообщение об ошибке

the error msg

Пример кода, который вызывает исключение

public void CreateInvoice()
    {
        String path = @"";
        FaktNT.OLESrvClass OLESrv = null;

        try
        {
            OLESrv = new FaktNT.OLESrvClass();
            if (OLESrv.MandantLogin2() == 0)
            {
                try
                {
                    //Do Stuff
                }
                catch (System.Exception ex)
                {
                    //Log Error
                    throw;
                }
                finally
                {
                    OLESrv.MandantLogout();
                }
            }
            else
            {
                 //Do Stuff
            };
        }
        finally
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(OLESrv);
            OLESrv = null;
            GC.Collect();
        }
    }

Ответы [ 3 ]

1 голос
/ 26 мая 2011

Это не сообщение .NET, сам компонент перехватывает исключение нарушения доступа. Похоже, это было написано в Delphi, судя по названию исключения. Создание бомбы с собственным кодом на AV обычно не требует большой помощи. Но, конечно, вы можете использовать компонент «неправильно». Вы потушили слишком много кода, чтобы сделать обоснованное предположение. Кроме того, выполнение вызовов в блоке finally после того, как вы поймали все исключения, которые он может вызвать, является плохой идеей.

Заставить его бомбить при выходе из программы, а не после вызова GC.Collect (). Верный признак того, что вам не удалось вызвать ReleaseComObject и обнулить все ссылки на интерфейс. Это обычное дело, лучше оставить это на сборщик мусора, чтобы сделать это правильно. Хотя это окно сообщения будет бомбить поток финализатора. Да, вам, вероятно, понадобится помощь поставщика, если тщательный анализ кода не поможет.

1 голос
/ 31 мая 2011

Я решил проблему сейчас.фактически я неправильно использовал COM-объект, я пропустил вызов OLESrv.EngineClose (), который аккуратно закрывает COM-объект.

каким-то образом этот маленький кусочек важной информации не попал в документацию продавцов ...

1 голос
/ 26 мая 2011

Вам не нужно освобождать COM-объект вручную с помощью Marshal.ReleaseComObject (). Это делается с помощью .net автоматически (в зависимости от того, что вы делаете с подсчетом ссылок в собственном коде COM, конечно).

Я бы также попытался проверить, возникла ли проблема на нативной стороне (например, в деструкторе, который вызывается, когда объект собирается мусором).

Генерирует ли COM-библиотека какие-либо собственные потоки, которые могут быть запущены после того, как объект был собран мусором?

...