ManualResetEvent在Mono中无法按预期工作

时间:2018-06-20 14:12:43

标签: c# sockets

我正在使用带有tcp的套接字将数据发送到远程服务器。我正在使用ManualResetEvent和System.Timers.Timer来缓解无法连接到远程主机的情况。要么使用成功的连接调用ConnectedCallback,否则连接将设置ManualResetEvent或它无法连接,并退回到计时器,计时器应关闭套接字并告诉主线程继续并处理未连接状态。

该逻辑工作正常,因为我使用简单的布尔值进行了尝试,不确定是否使用了ManualResetEvent对象?

我还应该添加一个针对.NET Frameworks 4.6的类库,它位于Mono中 代码:

public void StartConnect()
{
    ConnectCue.Reset();
    // Retrieve server config
    var serverConfig = LocalConfig.GetConfig<VmeServerConfig>();

    var ipHostInfo = Dns.GetHostEntry(serverConfig.BaseAddress);
    var ipAddress = ipHostInfo.AddressList[0];

#if DEBUG
    var remoteEp = new IPEndPoint(IPAddress.Loopback, Port);
#else
    var remoteEp = new IPEndPoint(ipAddress, Port);
#endif

    // Create a TCP/IP socket.  
    TcpSocket = new Socket(ipAddress.AddressFamily,
        SocketType.Stream, ProtocolType.Tcp)
    {
        ReceiveTimeout = serverConfig.Timeout * 1000,
        SendTimeout = serverConfig.Timeout * 1000
    };

    // Connect to the remote endpoint
    TcpSocket.BeginConnect(remoteEp,
        new AsyncCallback(ConnectedCallback), TcpSocket);


    // Timer that will signal main thread to continue
    var timeoutTimer = new System.Timers.Timer()
    {
        Interval = serverConfig.Timeout * 1000,
        AutoReset = false,
        Enabled = true
    };

    // Event to singal thread to continue if connection takes long
    timeoutTimer.Elapsed += delegate (object sender, ElapsedEventArgs args)
    {
        // Nothing to do here
        if (IsConnected)
            return;

#if DEBUG
    Interface.RootLogger.Write(LogType.Warning, "TICK: Not connected");       
#endif
        ConnectCue.Set();                
        TcpSocket.Shutdown(SocketShutdown.Both);
        TcpSocket.Close();
    };


    timeoutTimer.Start();

    // Cue the main thread
    ConnectCue.WaitOne();

    if (IsConnected) return;

    //Not connected, handle stuff...
}

/// <summary>
/// Invoked when a connection to the service has been made or not been made
/// </summary>
/// <param name="ar"></param>
private void ConnectedCallback(IAsyncResult ar)
{

    // Retrieve the socket from the state object.  
    var tcpSocket = (Socket)ar.AsyncState;


    // If we couldn't then its been handled by timeout
    if (!tcpSocket.Connected)
        return;

    try
    {
        //doing stuff..
    }
    catch (System.Exception)
    {
        tcpSocket.Close();
        throw;
    }

    // Signal the main thread that the connection has been made.  
    ConnectCue.Set();
}

0 个答案:

没有答案