private void EndGetAllMappingsInternal(IAsyncResult result) { EndMessageInternal(result); GetAllMappingsAsyncResult mappingResult = result.AsyncState as GetAllMappingsAsyncResult; GetGenericPortMappingEntryResponseMessage message = mappingResult.SavedMessage as GetGenericPortMappingEntryResponseMessage; if (message != null) { Mapping mapping = new Mapping(message.Protocol, message.InternalPort, message.ExternalPort, message.LeaseDuration); mapping.Description = message.PortMappingDescription; mappingResult.Mappings.Add(mapping); GetGenericPortMappingEntry next = new GetGenericPortMappingEntry(mappingResult.Mappings.Count, this); // It's ok to do this synchronously because we should already be on anther thread // and this won't block the user. byte[] body; WebRequest request = next.Encode(out body); if (body.Length > 0) { request.ContentLength = body.Length; request.GetRequestStream().Write(body, 0, body.Length); } mappingResult.Request = request; request.BeginGetResponse(EndGetAllMappingsInternal, mappingResult); return; } CompleteMessage(result); }
public override async Task <Mapping []> GetAllMappingsAsync() { var mappings = new List <Mapping> (); // Is it OK to hardcode 1000 mappings as the maximum? Probably better than an infinite loop // which would rely on routers correctly reporting all the mappings have been retrieved... try { for (int i = 0; i < 1000; i++) { var message = new GetGenericPortMappingEntry(i, this); // If we get a null response, or it's the wrong type, bail out. // It means we've iterated over the entire array. var resp = await SendMessageAsync(message).ConfigureAwait(false); if (!(resp is GetGenericPortMappingEntryResponseMessage response)) { break; } mappings.Add(new Mapping(response.Protocol, response.InternalPort, response.ExternalPort, response.LeaseDuration, response.PortMappingDescription)); } } catch (MappingException ex) { // Error code 713 means we successfully iterated to the end of the array and have all the mappings. // Exception driven code flow ftw! if (ex.ErrorCode != ErrorCode.SpecifiedArrayIndexInvalid) { throw; } } return(mappings.ToArray()); }
public override IAsyncResult BeginGetAllMappings(AsyncCallback callback, object asyncState) { GetGenericPortMappingEntry message = new GetGenericPortMappingEntry(0, this); return(BeginMessageInternal(message, callback, asyncState, EndGetAllMappingsInternal)); }