private static void PutEntry(IPAddress ip, CachedIPHostEntry entry) { lock (CachedIPHostEntryDict) { if (CachedIPHostEntryDict.TryAdd(ip, entry)) { LogHelper.Debug($"Start resolve IPHostEntry for {ip}: IsResolved={entry.IsResolved}, HasErrors={entry.HasErrors}, ToolTipText={entry.DisplayText}"); } else { CachedIPHostEntryDict[ip] = entry; LogHelper.Debug($"End resolve IPHostEntry for {ip}: IsResolved={entry.IsResolved}, HasErrors={entry.HasErrors}, ToolTipText={entry.DisplayText}"); } } }
public static async Task <bool?> ResolveIpAddress(string ip, Action <CachedIPHostEntry> callback = null) { return(await Task.Run(() => { if (!IsIPValid(ip)) { callback?.Invoke(CachedIPHostEntry.EMTPY); return false; } IPAddress ipa = null; try { ipa = IPAddress.Parse(ip); if (CachedIPHostEntryDict.TryGetValue(ipa, out var entry)) { if (entry.IsResolved || entry.HasErrors) { callback?.Invoke(entry); return true; } NotifyCollectionChangedEventHandler add = (sender, args) => { if (args.Action == NotifyCollectionChangedAction.Replace) { var entry = (KeyValuePair <IPAddress, CachedIPHostEntry>)args.NewItems[0]; if (entry.Key == ipa) { callback?.Invoke(entry.Value); } } }; CachedIPHostEntryDict.CollectionChanged += add; CachedIPHostEntryDict.CollectionChanged += (s, e) => CachedIPHostEntryDict.CollectionChanged -= add; return (bool?)null; } else { PutEntry(ipa, CachedIPHostEntry.RESOLVING); // reserve slot callback?.Invoke(CachedIPHostEntry.RESOLVING); // http://www.dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Net/System/Net/DNS@cs/1305376/DNS@cs IPHostEntry resolvedEntry = System.Net.Dns.GetHostEntry(ipa); PutEntry(ipa, CachedIPHostEntry.WrapHostEntry(resolvedEntry)); callback?.Invoke(CachedIPHostEntryDict[ipa]); return true; } } catch (Exception e) { LogHelper.Debug($"Unable to resolve {ip}, message was {e.Message}"); var ret = CachedIPHostEntry.CreateErrorEntry(ipa, e); PutEntry(ipa, ret); callback?.Invoke(ret); return false; } }).ConfigureAwait(false)); }