/// <summary> /// Handles async host lookup completions. /// </summary> /// <param name="ar"></param> private static void OnGetHostByName(IAsyncResult ar) { // Queue operations that completed synchronously so that they'll // be dispatched on a different thread. ar = QueuedAsyncResult.QueueSynchronous(ar, onGetHostByName); if (ar == null) { return; } // Handle the completion EnhancedDnsResult dnsAR = (EnhancedDnsResult)ar.AsyncState; try { dnsAR.HostEntry = Dns.EndGetHostEntry(ar); dnsAR.Notify(); } catch (Exception e) { dnsAR.Notify(e); } }
//--------------------------------------------------------------------- // Implementation Note: // // I'm going to perform the cache lookup in BeginGetHostByName() and // if I find the entry and it hasn't expired, I'll set the HostEntry // field in the async result as well as setting Cached=true. EndGetHostByName() // will be able to distinguish between a cached and non-cached situations // by looking at the Cached field. /// <summary> /// Initiates an asynchronous operation to perform an host name lookup. /// </summary> /// <param name="host">The host name.</param> /// <param name="callback">The operation completion callback (or <c>null</c>).</param> /// <param name="state">Application state.</param> /// <returns>The asynchronous result used to track the operation.</returns> public static IAsyncResult BeginGetHostByName(string host, AsyncCallback callback, object state) { var dnsAR = new EnhancedDnsResult("SafeDns", callback, state); DnsRecord dnsRec = null; dnsAR.Host = host.ToUpper(); // Doing this once if (enableCache) { lock (syncLock) { dnsRec = (DnsRecord)cache[dnsAR.Host]; if (dnsRec != null) { if (dnsRec.TTD <= SysTime.Now) { // Remove expired entries cache.Remove(dnsRec.Host); dnsRec = null; } } } } if (dnsRec == null) { Dns.BeginGetHostEntry(host, onGetHostByName, dnsAR); dnsAR.Started(); } else { dnsAR.HostEntry = dnsRec.Entry; dnsAR.Cached = true; dnsAR.Started(); dnsAR.Notify(); // Indicate completion } return(dnsAR); }