事件处理程序在.dll中始终为 null,从另一个类订阅

本文关键字:另一个 null 程序 dll 事件处理 | 更新日期: 2023-09-27 18:32:44

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

以下是简化的代码:

服务器.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));
        }
    }
}

程序.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);
    }
}

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

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

事件处理程序在.dll中始终为 null,从另一个类订阅

如果没有一个好的、最小的、完整的和可验证的例子,就不可能确定问题是什么。但是,根据您在此处发布的内容,在我看来,调用的ConnectClient()方法与您之前用于订阅事件的方法属于不同的实例(实际上是完全不同的类型(。

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

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


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

  1. Server类内部拉出clientService,让它成为继承Server的顶级类。(同时,考虑重命名类型,以便它使用 Pascal 大小写而不是驼峰大小写,按照正常的 .NET 约定...即调用它 ClientService (。

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

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