情况:我为自己写了一个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 中为空。
答案 0 :(得分:1)
如果没有好的Minimal, Complete, and Verifiable example,就无法确定问题是什么。但是,根据您在此处发布的内容,在我看来,被调用的ConnectClient()
方法属于与您不同的实例(实际上是完全不同的类型)之前用于订阅活动。
您的程序会创建Server
的实例,然后订阅该实例的ClientConnected
事件。您没有显示对ConnectClient()
的调用,但我看不到Server
类中存在任何此类方法的证据。它只在clientService
类中。您也不会显示该类的任何实例,但它肯定不能是您在所显示的代码中订阅的Server
实例。
因此,如果您实际上在ConnectClient()
的实例上调用clientService
,那么这与您订阅的事件的Server
对象完全不同。由于没有代码订阅clientService
实例的事件,因此事件字段当然仍设置为null
。
同样,如果没有一个好的代码示例,就不可能确切地知道解决这个问题的最佳方法是什么。但似乎您需要进行两项更改:
从clientService
类中拉出Server
,然后将其设为继承Server
的顶级类。 (同时,考虑重命名类型,使其使用Pascal case而不是camel-case,按照正常的.NET约定......即称之为ClientService
)。
不是在Server
方法中创建Main()
的实例,而是创建clientService
的实例。
您还需要进行更改,以删除代码中其他位置{/ 1}} 所做的任何实例的用法,但我不能对此发表评论,因为您没有不要在代码示例中包含它。