/// <summary> /// Raise the QueryFinished event with the specified parameters /// </summary> /// <param name="response">Response to the query (success, failure, etc)</param> /// <param name="queryType">Type of query that finished</param> /// <param name="payload">Received data packet</param> private void OnQueryFinished(UDPServerQueryState queryState, UDPPacket payload) { UDPServerQueryResponseHandler queryFinished = this.QueryFinished; if (queryFinished != null) { queryFinished(this, queryState.QueryResponse, queryState.QueryType, payload); } }
/// <summary> /// Start an asynchronous query operation /// </summary> /// <param name="timeout">Timeout (in seconds) to wait for a response from the server or zero for no timeout</param> public void BeginQuery(int timeout, UDPServerQueryType queryType, IPAddress address, int queryPort) { remoteEndpoint = new IPEndPoint(address, queryPort); // Start the query thread UDPServerQueryState queryState = new UDPServerQueryState(new ParameterizedThreadStart(QueryThreadProc), new TimerCallback(QueryTimeoutCallback), queryType); lock (activeQueryLock) { activeQueries.Add(queryState); } queryState.Start(timeout); }
/// <summary> /// Callback function for when the timeout timer expires /// </summary> /// <param name="state"></param> private void QueryTimeoutCallback(object state) { UDPServerQueryState queryState = (UDPServerQueryState)state; // Flag the timeout condition queryState.QueryResponse = UDPServerQueryResponse.Timeout; queryState.End(); OnQueryFinished(queryState, null); lock (activeQueryLock) { activeQueries.Remove(queryState); } }
/// <summary> /// Thread function where the query is actually executed. The call to Receive() is blocking and the /// separate timer thread takes care of the timeout behaviour (if specified) /// </summary> private void QueryThreadProc(object oQueryState) { UDPServerQueryState queryState = (UDPServerQueryState)oQueryState; try { // Send the query to the server OutboundPacket query = new OutboundPacket(true); query.Append((byte)queryState.QueryType); Send(queryState.QueryClient, query); // Wait for a response from the server UDPPacket queryResponse = Receive(queryState.QueryClient); // Stop the timeout timer queryState.End(); if (queryState.QueryResponse == UDPServerQueryResponse.None) { queryState.QueryResponse = UDPServerQueryResponse.Success; OnQueryFinished(queryState, queryResponse); } } catch (ThreadAbortException) { } catch (Exception) { if (queryState.QueryResponse != UDPServerQueryResponse.Timeout) { queryState.QueryResponse = UDPServerQueryResponse.Error; // Stop the timeout timer queryState.End(); OnQueryFinished(queryState, null); } } lock (activeQueryLock) { activeQueries.Remove(queryState); } }