异步套接字服务器长时间运行任务

时间:2018-08-20 17:38:02

标签: c# sockets asynchronous

我的问题可能很荒谬,但我无法在线找到任何信息。

我的服务器不断读取从与其连接的客户端发送的数据,根据接收到的数据,我执行某些操作。

我的问题是,如果我的操作很长,我是否需要创建一个新线程,以便不会阻止BeginRecieve?如果没有,我该怎么办?

代码:

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        Socket current = (Socket)ar.AsyncState;
        int received;
        try
        {
            received = current.EndReceive(ar);
        }
        catch
        {
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(buffer, recBuf, received);
        var st = Helper.ByteToObject(recBuf);
        if ((st is string s))
        {
            if (s == "Something")
            {
                //Long operating task, do i need to use a new thread?
            }
        }
        current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
    }
    catch
    {
        return;
    }
}

1 个答案:

答案 0 :(得分:1)

处理长时间运行的任务的最佳方法是启动一个线程并将任务信息上交至该线程。这样一来,您的主线程便可以继续从客户端接收数据,而另一个线程则可以继续进行所需的实际工作。

我通常的实现方式是为每个需要任务输入的唯一任务定义一个函数,并在需要时由主任务启动。然后,我保留一个向量来容纳所有线程句柄,以便我们可以跟踪线程。

您将需要一种方法来同步线程正在执行的任务的结果,这最终可能会导致创建竞争条件,因此您将需要添加互斥量以防止出现问题。您可能还想创建一个处理队列,该队列将由客户端发送的消息填充,因为您不想最终获得数千个线程。

我通常将线程限制设置为等于其正在运行的系统上的硬件线程,并且当我需要线程时,我只会旋转那么多线程。该队列将允许未处理的数据等待线程完成其任务并变得可用。

有很多方法可以做到这一点,并且没有真正正确的答案