gpt4 book ai didi

c# - "Delegate to an instance method cannot have null ' 这个' "转发事件时

转载 作者:行者123 更新时间:2023-11-30 19:59:48 26 4
gpt4 key购买 nike

我正在尝试将事件 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);
}
}

服务器.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'
我做错了什么或者这不是转发事件的正确方法吗?

最佳答案

这是非常独特的,从来没有见过有人这样做过。这是 .NET Framework 中的回归,3.5 为您提供了一个更好的异常(exception)。基本问题是您让事件自己订阅。重现崩溃的简单版本:

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() 方法。

关于c# - "Delegate to an instance method cannot have null ' 这个' "转发事件时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22887612/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com