如何使用 C# 中的 TimerCallback 中断在不同线程中运行的循环?

发布于 2024-09-27 01:17:36 字数 262 浏览 1 评论 0原文

我正在编写一个有时间限制的游戏服务器。我将通过套接字接受输入,直到计时器完成。我正在使用永远循环从客户端接收数据。

while(true)
{
    socket.Receive(buffer);
} 

当时间限制结束时,我需要打破这个循环。

抱歉,我认为我不够具体。

我有两个玩家异步发送和接收数据。计时器用于记录双方玩家的时间。我需要结束对两个玩家的数据接收,并在计时器结束时返回有关他们游戏的统计数据。

I am writing a game server that has a time limit. I will be accepting input accross a socket until the timer is done. I am using a forever loop to receive data from the client.

while(true)
{
    socket.Receive(buffer);
} 

I need to break out of this loop when the time limit ends.

Sorry I don't think I am being specific enough.

I have two players sending and receiving data asynchronously. The timer is used to keep track of the time for both players. I need to end the reception of data from both players and give back statistics about their game at the end of the timer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

私野 2024-10-04 01:17:36

处理这个问题的最佳方法是让带有计时器的ad调用套接字接收方法所在的类中的停止方法。此类将有一个 AutoResetEvent 成员实例,并在套接字读取期间检查事件以查看是否需要停止:

public class SomeClass {
    AutoResetEvent _stopEvent = new AutoResetEvent(false);
    Socket _socket;
    public void StopReceive() {
        _stopEvent.Set();
    }
    private void SomeMethod() {
        _socket.ReceiveTimeout = 5000;  // In milliseconds
        while(!_stopEvent.WaitOne(0)){
                _socket.Receive(buffer);
        }
    }
}

编辑:
如果两个不同线程上的两个玩家有两个套接字,而第三个线程处理超时,则所有三个线程中的代码都需要访问同一事件,并将该事件更改为 ManualResetEvent。我不确定的是,是否有一个类处理计时器线程,另一个类处理两个玩家的套接字读取线程,或者它们是否由一个类处理。如果它们是单独的类,那么对于上述代码,您可以在构造函数中传递事件:

public class SomeClass {
    ManualResetEvent _stopEvent;
    Socket _socket;
    public SomeClass(ManualResetEvent stopEvent) {
        _stopEvent = stopEvent;
    }
    private void SomeMethod() {
        _socket.ReceiveTimeout = 5000;  // In milliseconds
        while(!_stopEvent.WaitOne(0)){
                _socket.Receive(buffer);
        }
    }
}

计时器线程现在可以调用 ManualResetEvent 实例中的 Set() 方法,并且两个 while 循环都将终止。

The best way to handle this is for the thead with the timer to call a stop method in the class where the socket receive method is. This class will have a AutoResetEvent member instance and in the while for the socket read check the event to see if you need to stop:

public class SomeClass {
    AutoResetEvent _stopEvent = new AutoResetEvent(false);
    Socket _socket;
    public void StopReceive() {
        _stopEvent.Set();
    }
    private void SomeMethod() {
        _socket.ReceiveTimeout = 5000;  // In milliseconds
        while(!_stopEvent.WaitOne(0)){
                _socket.Receive(buffer);
        }
    }
}

Edit:
If you have two sockets for the two players on two different threads, with the third thread handling the timeout then the code in all three threads need access to the same event, and change the event to a ManualResetEvent. What I am not sure about is if you have one class that handles the timer thread, and another class that handles the socket read threads for the two players, or if they are handled by one class. If they are separate classes then for the above code you could pass the event in the constructor:

public class SomeClass {
    ManualResetEvent _stopEvent;
    Socket _socket;
    public SomeClass(ManualResetEvent stopEvent) {
        _stopEvent = stopEvent;
    }
    private void SomeMethod() {
        _socket.ReceiveTimeout = 5000;  // In milliseconds
        while(!_stopEvent.WaitOne(0)){
                _socket.Receive(buffer);
        }
    }
}

The timer thread could now call the Set() method in the ManualResetEvent instance and both while loops would terminate.

梦中楼上月下 2024-10-04 01:17:36

让看门狗定时器在超时到期时关闭套接字。它将导致您的 socket.Receive 调用出现 SocketException,因此准备来捕获它。我将相同的机制用于不同的目的。

解决方案 2:http://msdn.microsoft。 com/en-us/library/system.net.sockets.socket.receivetimeout.aspx 但我不知道它是否可以应用于您的情况。

或者,您可以查询套接字的可用属性,该属性指示有多少字节可供读取。但这涉及轮询/自旋锁,这对性能不利。即使您想使用信号量(这使您有机会设置最大超时),您仍然需要“有人”在数据可用时释放它

Have a watchdog timer close the socket when timeout expires. It will cause a SocketException on your socket.Receive call so be prepared to catch it. I use the same mechanism for different purposes.

Solution 2: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receivetimeout.aspx but I don't know if it can be applied to your case.

Or, else, you might query the Available property of the socket that indicates how many bytes are ready to be read. But this involves a polling/spinlock, which is bad for performance. Even if you wanted to use a semaphore, which gives you the opportunity to set a maximum timeout, you still need "somebody" to release it when data is available

浅忆流年 2024-10-04 01:17:36

我在想,而不是创建一个无限循环。我可能会使用非阻塞套接字。

while(stillTime)
{
    if(socket.Available > 0)
    socket.Recieve(buffer);
}

当计时器关闭时,将 stillTime 设置为 false。

这是更好的解决方案吗?

I was Thinking that instead of creating an infinite loop. I could possibly use a non-blocking socket.

while(stillTime)
{
    if(socket.Available > 0)
    socket.Recieve(buffer);
}

And when timer goes off set stillTime to false.

Is this a better solution?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文