.net Sock.BeginReceive并阻止EndReceive

时间:2013-08-02 10:05:41

标签: .net

我使用了.Net的Socket.BeginReceive方法,而我从EndReceive方法获取数据我使用AutoResetEvent.waitone块无限地使用EndReceive代码线程我发现BeginReceive无法工作;所有线程都被阻止;在计时器结束之前我什么也得不到,并发出信号,我可以再次获得数据。 BeginReceive不是异步方法?

var sock= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

sock.BeginReceive(buffer, 0, 1024, SocketFlags.None, i => {
    var sock= (Socket)i.AsyncState;
    int readNum=sock.EndReceive(i);
    var reset= new AutoResetEvent(false);
    Timer timer = new Timer({ Thread.Sleep(1000000000); reset.set() });

    reset.WaitOne(Timeout.Infinite);
    time.Dispose();
} ,sock);

仅仅处理计时器我必须创建新线程才能等待!!

1 个答案:

答案 0 :(得分:0)

AutoResetEvente包含在临时闭包中,因此为处理EndReceive代码而创建的线程将无限期地等待。

最好将代码重构为以下内容:

bool stopped = false;
var timer = null;

void MainFunction()
{
    var buffer = new byte[1024];
    var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    sock.BeginReceive(buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReadCallback), sock);
}

void ReadCallback(IAsyncResult ar)
{
    var sock = (Socket)ar.AsyncState;

    int readNum = sock.EndReceive(ar);

    // begin receiving again as long as we shouldn't be stopped
    if (stopped == false)
    {
        sock.BeginReceive(buffer, 0, 1024, SocketFlags.None, new AsyncCallback(ReadCallback), sock);
    }

    if (timer == null)
    {
        Timer timer = new Timer({ Thread.Sleep(1000000000); stopped = true; });
    }
}

您需要Set AutoResetEvent表示资源是免费的。我在你提供的内容中看不到任何代码。

您可能需要查看http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx

上的一些示例和文档