EventHandler在.dll中始终为null,从另一个类订阅

时间:2016-02-01 18:47:20

标签: c# class events dll .net-4.5

情况:我为自己写了一个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)。我不知道为什么,这个eventhandler总是为null。我阅读了2页谷歌搜索结果,但没有一个帮助。

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

1 个答案:

答案 0 :(得分:1)

如果没有好的Minimal, Complete, and Verifiable example,就无法确定问题是什么。但是,根据您在此处发布的内容,在我看来,被调用的ConnectClient()方法属于与您不同的实例(实际上是完全不同的类型)之前用于订阅活动。

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

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


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

  1. clientService类中拉出Server,然后将其设为继承Server的顶级类。 (同时,考虑重命名类型,使其使用Pascal case而不是camel-case,按照正常的.NET约定......即称之为ClientService)。

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

  3. 您还需要进行更改,以删除代码中其他位置{/ 1}} 所做的任何实例的用法,但我不能对此发表评论,因为您没有不要在代码示例中包含它。