C #: правильное удаление объектов C # при создании с помощью COM Interop из VB6 - PullRequest
6 голосов
/ 02 августа 2010

Я пишу компонент библиотеки классов C #, который будет выступать в качестве TCP-сервера. Он будет прослушивать и получать XML через определенный порт, десериализовывать его, а затем вызывать события, содержащие результирующий объект, в качестве аргумента события.

Сама библиотека классов будет использоваться приложением VB6, которое будет получать и обрабатывать события и связанные видимые объекты класса COM.

Класс TcpServer оборачивает функциональность TcpListener и не виден COM. Это обрабатывает соединения и вызывает события, связанные с соединениями, разъединениями и полученными данными.

sealed class TcpServer : IDisposable
{
    private readonly TcpListener tcpListener;
    private bool disposed = false;  

    public TcpServer(int port)
    {
        tcpListener = new TcpListener(IPAddress.Any, port);
        tcpListener.Start();
        tcpListener.BeginAcceptSocket(EndAcceptSocket, tcpListener);
    }

    ~TcpServer()
    {
        Dispose(false);
    }   

    // blah blah blah

    public void Dispose()
    {
        Dispose(true);
    }

    private void Dispose(bool disposing)
    {
        if (this.disposed == false)
        {
            if (disposing)
            {
                if (tcpListener != null)
                {
                    tcpListener.Stop();
                }
            }
            this.disposed = true;
        }
    }       
}

WUServer - это видимый COM-класс, который приложение VB6 создает и использует. Он упаковывает класс TcpServer и отвечает за десериализацию всех полученных данных и вызов соответствующего события с соответствующими аргументами события.

public class WUServer : IWUServer
{
    private TcpServer tcpServer;

    public WUServer()
    {
        tcpServer = new TcpServer(12345);
        tcpServer.DataReceived += new EventHandler<DataReceivedEventArgs>(tcpServer_DataReceived);
        tcpServer.SocketConnected += new EventHandler<IPEndPointEventArgs>(tcpServer_SocketConnected);
        tcpServer.SocketDisconnected += new EventHandler<IPEndPointEventArgs>(tcpServer_SocketDisconnected);
    }
}

Проблема, с которой я столкнулся, заключается в том, что класс TcpServer не удаляется приложением VB6 должным образом. Установка для экземпляра WUServer значения Nothing до закрытия приложения не приводит к удалению класса TcpServer, он продолжает зависать в сокете и приводит к ошибкам, если я пытаюсь снова запустить приложение VB6.

Если я использую класс WUServer из приложения C #, все в порядке, Dispose вызывается для TcpServer и сокет закрывается.

Как я должен убедиться, что класс TcpServer правильно удален, когда он создается косвенно приложением VB6?

1 Ответ

8 голосов
/ 02 августа 2010

вы можете добавить публичный метод к WUServer, который вы явно вызываете в VBA, внутри этого метода освободите ваш TCP-сервер

void Close()
{
 tcpServer.Dispose();
}
...