EventHandler 在 .dll 中始终为空,从另一个 class 订阅

EventHandler always null in .dll, subscribed from another class

情况:我为自己写了一个TCP/IP库。它是 .dll 文件中的一组 client.cs 和 server.cs。现在,我在同一个解决方案中有一个测试程序(客户端和服务器)。连接很好,我也可以通过多个客户端发送和接收消息。我的痛苦是我想创建一个 event;我阅读了 MSDN How-To,我遵循了委托方法,但是当我引发事件时(在我订阅它之后),它总是空的。 :(

这里是简化代码:

Server.cs

public class ClientConnectedEventArgs : EventArgs
{
    private string Clname = "";
    public ClientConnectedEventArgs(string clientname)
    {
        Clname = clientname;
    }

    public string ClientName
    {
        get { return Clname; }
        set { Clname = value; }
    }
}

public delegate void ClientConnectedEventHandler(object sender, ClientConnectedEventArgs e);

public class Server
{
    public event ClientConnectedEventHandler ClientConnected;

    protected virtual void OnClientConnected(ClientConnectedEventArgs e)
    {
        var temp = ClientConnected;
        if (temp != null) temp(this, e);
    }

    internal class clientService : Server
    {
        internal int ConnectClient(TcpClient newclient)
        {
            clname = ReceiveStringFrom();
            OnClientConnected(new ClientConnectedEventArgs(clname));
        }
    }
}

Program.cs(服务器测试控制台应用程序)

class Program
{
    static UniTcpIP.Server srv;
    static void Main(string[] args)
    {
        srv = new UniTcpIP.Server();
        srv.ClientConnected += new UniTcpIP.ClientConnectedEventHandler(srv_ClientConnected);
        if (srv.Start("127.0.0.1", 6969) == 0) Console.WriteLine("Server started");
    }

    static void srv_ClientConnected(object sender, UniTcpIP.ClientConnectedEventArgs e)
    {
        Console.WriteLine("CONNECTED: " + e.ClientName);
    }
}

我的目标是创建一个事件 (ClientConnected),该事件在客户端连接时触发。我不知道为什么,这个事件处理程序总是空的。我阅读了 2 页的 google 结果,但其中 none 有帮助。

一些调试信息: 当我在订阅后插入断点时,srv.ClientConnected 值为:{Method = {Void srv_ClientConnected(System.Object, UniTcpIP.ClientConnectedEventArgs)}} 但是,当事件被引发时,它在 Server.cs.

中为空

没有好的 Minimal, Complete, and Verifiable example,就不可能确定问题出在哪里。但是,根据您在此处发布的内容,在我看来,被调用的 ConnectClient() 方法属于一个不同的实例(实际上,一个完全不同的 type)您之前用来订阅事件的那个。

您的程序创建 Server 的实例,然后订阅该实例的 ClientConnected 事件。您没有显示对 ConnectClient() 的调用,但我没有看到 Server class 中甚至存在任何此类方法的证据。它仅在 clientService class 中。您也没有显示 class 的任何实例,但它肯定不能是您在显示的代码中订阅的 Server 的实例。

因此,如果您实际上是在 clientService 的实例上调用 ConnectClient(),那么该实例与您订阅其事件的 Server 对象完全不同。由于没有代码订阅 clientService 实例的事件,事件字段当然仍设置为 null.


同样,如果没有好的代码示例,就不可能确定解决此问题的最佳方法是什么。但您似乎可能需要进行两项更改:

  1. Server里面的clientService拉出来class,做个继承[=11=的顶层class就好了]. (同时,考虑重命名类型,使其使用 Pascal 大小写而不是驼峰式大小写,按照正常的 .NET 约定......即称它为 ClientService)。

  2. 不要在 Main() 方法中创建 Server 的实例,而是创建 clientService.

  3. 的实例

您还需要进行更改以删除您 did 在代码其他地方使用的任何 clientService 实例的用法,但我无法发表评论因为你没有在你的代码示例中包含它。