簡體   English   中英

C#:ManualResetEvent崩潰

[英]C#: Crash on ManualResetEvent

我使用這篇文章在msdn上作為主要助手編寫了代碼

我的代碼:

    private ManualResetEvent _AllDone = new ManualResetEvent(false);

    internal void Initialize(int port,string IP)
    {
        IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
        Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _Accpt.Bind(_Point);
        _Accpt.Listen(2);

        while (true)
        {
            _AllDone.Reset();
            _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
            _AllDone.WaitOne(); <<crash here
        }

    }

這就是發生的情況,我在BeginAccept處設置了一個斷點(我認為是有問題的),但是它可以正常執行。但是,當我嘗試執行“ _AllDone.WaitOne()”時-服務器崩潰。

如果_allDone無法在Win32窗體應用程序中使用-我該如何創建我的項目?

編輯

我忘了提一下我在Accept()中寫了_AllDone.Reset(),但是它沒有到​​那兒,我在那兒設置了一個斷點,但它沒有去。

    private void Accept(IAsyncResult async)
    {
        _AllDone.Set();
        Socket _Accpt = (Socket)async.AsyncState;
        Socket _Handler = _Accpt.EndAccept(async);

        StateObject _State = new StateObject();
        _State.workSocket = _Handler;

        _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);

    }

因此,如果我做對了,您想在收到套接字連接后立即重新啟動Accept ,而不要等到Accept完成后才開始,這就是為什么您不使用Accept的同步版本的原因。

因此,您是說將套接字連接到指定的地址和端口時,它不會觸發您的Accept方法? 因為這就是Accept所做的事情:它接受新的傳入連接,等待客戶端連接。 因此,這可能就是為什么您認為它“崩潰了”以及為什么它從未在您的Accept方法中到達您的代碼的原因。

提示:也許也看看Socket.AcceptAsync

編輯:要設置一個異步服務器來偵聽傳入的連接,您不需要任何ManualWaitEvent:

internal void Initialize(int port,string IP) {
    IPEndPoint _Point = new IPEndPoint(IPAddress.Parse(IP), port);
    Socket _Accpt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _Accpt.Bind(_Point);
    _Accpt.Listen(2);
    _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
}

private void Accept(IAsyncResult async) {
    Socket _Accpt = (Socket)async.AsyncState;
    Socket _Handler;
    try {
        _Handler = _Accpt.EndAccept(async);
    } finally {
        _Accpt.BeginAccept(null, 0, new AsyncCallback(Accept), _Accpt);
    }

    StateObject _State = new StateObject();
    _State.workSocket = _Handler;

    _Handler.BeginReceive(_State.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), _State);
}

注意:您還將需要退出條件,以便不調用BeginAccept(例如,當您要關閉服務器時)。

我認為Lucero試圖說的是,該應用程序正常工作,您可能會問為什么會這樣。

好吧,當您使用服務器端套接字應用程序時,您基本上要做的是讓服務器固定在端口上並等待連接到達。 當連接到達時,您將執行其余的代碼。

Lucero的意思是,雖然沒有消息到達服務器,但服務器一直處於等待狀態,這可能看起來像是凍結了一樣。

您的代碼中是否是這種情況?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM