在多线程套接字服务器上使用事件
Using events on multithreading socket server
我正在为一个新的游戏项目制作一个服务器,我正在为客户端和服务器使用 C# (.NET Framework v4.5)。
我目前正在使用类似的东西来管理我的玩家。
new Thread(() =>
{
connection.ListenAndSend();
}).Start();
public void ListenAndSend()
{
while(working)
{
if(someThingToRead)
{
//Listening logic here
//Here i call my event for dataReceived with the data i just read.
}
else if (queue.Count > 0)
{
Send(queue.Dequeue().Data); //Send data from the Queue
}
}
使用队列是因为我不应该从不同的线程访问流(我认为它会抛出 InvalidOperationException)所以我实现了队列以从同一个线程发送数据。
我认为这基本上没问题,但我担心这些事件。
事件正在触发并且工作正常,但我还没有对多个客户端进行测试,所以...
- 事件是否与侦听器线程在同一个线程中执行?
- 我会遇到多个线程同时修改字段的问题吗? (例如,我在 java 方面更有经验,我记得一些关于 Syncronize 界面的事情?)
- 现在还没有完成,但稍后可能会有一些事件最终调用发送方法,从而将数据添加到发送队列(但这应该不是问题,对吧?)
如果重要的话,这款游戏永远不会适合大量玩家(可能在 2 到 8 人之间)。
有什么我没发现的严重问题吗?
当我使用队列时,我认为哪个线程添加数据并不重要,但我的监听会在它执行事件代码时停止吗? (如果它真的在同一个线程上)虽然这不是真正的问题,但它会同时从多个线程访问字段吗?
更新:
我可以用 async/await 完成所有这些吗??我看不出如何以这种方式进行监听循环,但如果确实可行,请在答案中展开。
另外,这个answer说的恰恰相反
更新 2:
现在我已经测试了我的代码,我知道它工作正常。
正如评论中指出的那样,我本可以使用 async/await 和更少的线程来完成此操作,但是:
其中最好使用 async/await 而不是线程,请记住我的游戏服务器应该能够根据需要占用尽可能多的 cpu/memory 并且如果这样做的话它很好(的当然线程在不工作时调用睡眠)。我希望我的服务器 运行 尽可能接近实时。
我还想指出,我第一次开始处理我的逻辑时,游戏地图(大约 60k 个对象)的序列化花费了大约 600 毫秒(这将适用于每个客户端)所以我结束了将序列化作业移动到套接字线程。
考虑到这一点,谁认为使用 Async/Await 而不是 new Threads
会更好
PD:我说的只是我的服务器,游戏客户端确实在使用async/await与服务器通信。
你有 2 个选项,ether 锁定变量(不推荐)
How to lock a variable used in multiple threads
或使用调度程序从另一个线程调用方法Using the C# Dispatcher
如果您没有使用 WPF,您可以看看这个 link:how do I convert wpf dispatcher to winforms
我正在为一个新的游戏项目制作一个服务器,我正在为客户端和服务器使用 C# (.NET Framework v4.5)。
我目前正在使用类似的东西来管理我的玩家。
new Thread(() =>
{
connection.ListenAndSend();
}).Start();
public void ListenAndSend()
{
while(working)
{
if(someThingToRead)
{
//Listening logic here
//Here i call my event for dataReceived with the data i just read.
}
else if (queue.Count > 0)
{
Send(queue.Dequeue().Data); //Send data from the Queue
}
}
使用队列是因为我不应该从不同的线程访问流(我认为它会抛出 InvalidOperationException)所以我实现了队列以从同一个线程发送数据。
我认为这基本上没问题,但我担心这些事件。
事件正在触发并且工作正常,但我还没有对多个客户端进行测试,所以...
- 事件是否与侦听器线程在同一个线程中执行?
- 我会遇到多个线程同时修改字段的问题吗? (例如,我在 java 方面更有经验,我记得一些关于 Syncronize 界面的事情?)
- 现在还没有完成,但稍后可能会有一些事件最终调用发送方法,从而将数据添加到发送队列(但这应该不是问题,对吧?)
如果重要的话,这款游戏永远不会适合大量玩家(可能在 2 到 8 人之间)。
有什么我没发现的严重问题吗?
当我使用队列时,我认为哪个线程添加数据并不重要,但我的监听会在它执行事件代码时停止吗? (如果它真的在同一个线程上)虽然这不是真正的问题,但它会同时从多个线程访问字段吗?
更新:
我可以用 async/await 完成所有这些吗??我看不出如何以这种方式进行监听循环,但如果确实可行,请在答案中展开。
另外,这个answer说的恰恰相反
更新 2:
现在我已经测试了我的代码,我知道它工作正常。
正如评论中指出的那样,我本可以使用 async/await 和更少的线程来完成此操作,但是:
其中最好使用 async/await 而不是线程,请记住我的游戏服务器应该能够根据需要占用尽可能多的 cpu/memory 并且如果这样做的话它很好(的当然线程在不工作时调用睡眠)。我希望我的服务器 运行 尽可能接近实时。
我还想指出,我第一次开始处理我的逻辑时,游戏地图(大约 60k 个对象)的序列化花费了大约 600 毫秒(这将适用于每个客户端)所以我结束了将序列化作业移动到套接字线程。
考虑到这一点,谁认为使用 Async/Await 而不是 new Threads
会更好PD:我说的只是我的服务器,游戏客户端确实在使用async/await与服务器通信。
你有 2 个选项,ether 锁定变量(不推荐) How to lock a variable used in multiple threads
或使用调度程序从另一个线程调用方法Using the C# Dispatcher
如果您没有使用 WPF,您可以看看这个 link:how do I convert wpf dispatcher to winforms