我正试图将班级OnClientMessage
上的Client
个活动转发到班级Server
以外的我的图书馆。
Client.cs
public class Client
{
private TcpClient tcpClient;
private StreamWriter writer;
private Boolean alive = true;
private int id;
public delegate void OnClientMessageHandler(Client sender, String message);
public delegate void OnClientDisconnectHandler(Client sender);
public event OnClientMessageHandler OnClientMessage;
public event OnClientDisconnectHandler OnClientDisconnect;
public Client(TcpClient tcpClient, int id)
{
this.tcpClient = tcpClient;
this.id = id;
writer = new StreamWriter(tcpClient.GetStream());
new Thread(() =>
{
Listen(new StreamReader(tcpClient.GetStream()));
}).Start();
}
void Listen(StreamReader reader)
{
while (tcpClient.GetStream().DataAvailable && alive)
{
OnClientMessage(this, reader.ReadLine());
Thread.Sleep(150);
}
}
public void Write(String message)
{
writer.WriteLine(message);
writer.Flush();
}
public int GetID()
{
return id;
}
public void Close()
{
alive = false;
writer.Close();
tcpClient.Close();
OnClientDisconnect(this);
}
}
Server.cs
public class Server
{
private IPAddress serverIP;
private short serverPort;
private TcpListener serverListener;
private int serverClientCount;
public List<Client> serverClients = new List<Client>();
private Boolean running;
public delegate void OnClientMessageHandler(Client sender, String message);
public delegate void OnClientDisconnectHandler(Client sender);
public event OnClientMessageHandler OnClientMessage;
public event OnClientDisconnectHandler OnClientDisconnect;
public Server(IPAddress ip, short port, Boolean autoStart = true)
{
this.serverIP = ip;
this.serverPort = port;
if(autoStart)
OpenServer();
}
public void OpenServer()
{
serverListener = new TcpListener(serverIP, serverPort);
serverListener.Start();
running = true;
while (running)
{
if (serverListener.Pending())
{
TcpClient tcpClient = serverListener.AcceptTcpClient();
new Thread(() =>
{
Client client;
client = new Client(tcpClient, serverClientCount);
client.OnClientMessage += new Client.OnClientMessageHandler(OnClientMessage);
client.OnClientDisconnect += new Client.OnClientDisconnectHandler(OnClientDisconnect);
serverClients.Add(client);
serverClientCount++;
}).Start();
}
else
{
Thread.Sleep(150);
}
}
}
public void WriteToClient(Client client, String message)
{
client.Write(message);
}
public void WriteToAll(String message)
{
serverClients.ForEach(client => client.Write(message));
}
public void Shutdown()
{
running = false;
serverClients.ForEach(client => client.Close());
serverListener.Stop();
}
}
现在,当事件发生时,应用程序崩溃Delegate to an instance method cannot have null 'this'
我做错了什么或者这不是转发活动的正确方法吗?
答案 0 :(得分:6)
这是非常独特的,从来没有见过任何人这样做。它是.NET Framework中的一个回归,3.5为您提供了一个更好的例外。基本问题是您自己订阅了事件。一个简单的版本来重现崩溃:
using System;
class Program {
public static event Action Kaboom;
static void Main(string[] args) {
Kaboom += new Action(Kaboom); // 3.5 raises an exception here
var handler = Kaboom;
if (handler != null) handler(); // kaboom
}
}
你实际上并没有“转发”这个事件。解开你的名字和代码。比方说,添加一个Fire()方法。