了解异步服务器套接字中的ManualResetEvent

时间:2013-03-31 12:47:56

标签: c# asyncsocket

Socket SocketSrv;
public static ManualResetEvent Done = new ManualResetEvent(false);
IPEndPoint IPP = new IPEndPoint(IPAddress.Any, 1234);

void Listening()
{
    SocketSrv = new Socket(AddressFamily.InterNetwork,
                           SocketType.Stream, ProtocolType.Tcp);
    try
    {
        SocketSrv.Bind(IPP);
        SocketSrv.Listen(5);

        while (true)
        {
            Done.Reset();
            info.Text = "Waiting for connections....";
            SocketSrv.BeginAccept(new AsyncCallback(Connection),
                                  SocketSrv);
            Done.WaitOne();
        }
    }
    catch(Exception error)
    {
        MessageBox.Show(error.Message);
    }
}

void Connection(IAsyncResult ar)
{
    Done.Set();
    Socket con= (Socket)ar.AsyncState;
    Socket handler = con.EndAccept(ar); 
}

我正在尝试理解此异步操作中的ManualResetEvent,因为我从未使用它。

  • 步骤1。创建SocketSrv以接受TCP连接,发送和接收“命令”的类型为流。

  • 第二步。套接字与ip,端口绑定,然后我们开始监听连接。

  • 第三步。在while循环中:

    • ManualResetEvent正在重置(我知道ManualResetEvent是一个类型为布尔值的类,表示线程忙或不忙。)在这种情况下,事件总是重置,因为如果有连接而另一个连接,我需要重置它并再次开始“操作”。

    • BeingAccept我正在启动异步操作时,执行的回调函数和将成为“套接字”的IAsyncResult参数。

  • 步骤4。 ResetEvent现在正在等待阻塞当前线程并等待连接方法中的处理程序结束,以便它可以完成初始化当前连接。

  • 步骤5。在连接线程中,ResetEvent将信号设置为true,这意味着......我不知道它意味着什么。我认为它告诉ResetEvent取消阻止主线程。

在'con'套接字中我得到AsyncState。我不知道它意味着什么。

在处理程序套接字中,我告诉ResetEvent已建立连接。

有人说,有人可以告诉我,我所说的是真是错,为什么?

1 个答案:

答案 0 :(得分:1)

使用该事件,以便在发生连接时BeginAccept在调用Connect方法之前不会再次调用WaitOne。例如Set暂停线程,直到调用Reset。调用WaitOne将事件的状态设置回信号,以便Connect再次停止线程,以便等待BeginAccept再次被调用。

就个人而言,我不使用这种特殊模式。我从未见过这种模式的解释。如果Connect循环和BeginAccept方法之间存在某些共享状态,则可能有意义。但是,正如所写的那样,任何国家都不会因使用该事件而受到保护。当我使用AysncState时,我根本就不使用事件,并且我已经使用这样的代码来处理许多连接。使用事件将无效以防止一次连接过多的错误。坦率地说,使用异步方法并强制它实现同步失败的目的。

BeginAccept的角度来看,BeginAccept只是不透明的数据。它是用于特定异步操作的“状态”。这个“状态”是特定于应用程序的。当您想要异步处理连接时,可以使用所需的任何内容。在EndAccept回调的情况下,您通常希望对服务器套接字执行某些操作,并将其传入状态,以便您可以访问它以调用SocketSrv。由于SocketSrv.BeginAccept(new AsyncCallback(Connection), null); //... void Connection(IAsyncResult ar) { Socket handler = SocketSrv.EndAccept(ar); //... } 是一个成员字段,您实际上并不需要 来执行此操作,您可以这样做:

Connection

您的评论似乎表明您已经很好地掌握了这一段代码。你的“Step4”有点偏,它不是等待Set方法结束,只是为了它 start (因为Set被称为第一行)。是的,“Step5”,WaitOne表示它取消阻止Reset,因此主线程调用BeginAccept然后{{1}}。