/// <summary> /// Queues a new image request. The request will be taken care of by an async operation. /// </summary> /// <param name="orgionalRequest">The image request</param> public void QueueImageRequest(ImageManagerRequest orgionalRequest) { // Validate if (String.IsNullOrWhiteSpace(orgionalRequest.Url)) { throw new Exception("You must supply both a ULR and callback"); } ImageManagerRequestInternal serviceRequest = null; // Lock the list lock (m_requestList) { // Add the current request to the back of the list. m_requestList.Add(new ImageManagerRequestInternal(orgionalRequest)); // Check if we should make the request now or not. If we don't // when a request finishes it will pick up the new request. for (int i = 0; i < MAX_RUNNING_IMAGE_REQUESTS; i++) { if (m_requestList.Count > i && !m_requestList[i].isServicing) { serviceRequest = m_requestList[i]; serviceRequest.isServicing = true; break; } } } if (serviceRequest != null) { // Kick off a new thread to service the request. Task.Run(async() => { await ServiceRequest(serviceRequest); }); } }
/// <summary> /// Used to service the given request. Once the image has been responded to the /// function will continue with requests until the queue is empty /// </summary> /// <param name="startingRequestedContext">The request to start with</param> /// <returns></returns> private async Task ServiceRequest(ImageManagerRequestInternal startingRequestedContext) { ImageManagerRequestInternal currentRequest = startingRequestedContext; while (currentRequest != null) { // Service the request in a try catch try { string fileName = MakeFileNameFromUrl(currentRequest.Context.Url); // First check if we have the file if (m_baconMan.CacheMan.HasFileCached(fileName)) { // If we have it cached pull it from there } else { // If not we have to get the image IBuffer imgBuffer = await m_baconMan.NetworkMan.MakeRawGetRequest(currentRequest.Context.Url); // Turn the stream into an image InMemoryRandomAccessStream imageStream = new InMemoryRandomAccessStream(); Stream readStream = imgBuffer.AsStream(); Stream writeStream = imageStream.AsStreamForWrite(); // Copy the buffer // #todo perf - THERE HAS TO BE A BTTER WAY TO DO THIS. readStream.CopyTo(writeStream); writeStream.Flush(); // Seek to the start. imageStream.Seek(0); // Create a response ImageManagerResponseEventArgs response = new ImageManagerResponseEventArgs() { ImageStream = imageStream, Request = currentRequest.Context, Success = true }; // Fire the callback currentRequest.Context.m_onRequestComplete.Raise(currentRequest.Context, response); } } catch (Exception e) { // Report the error m_baconMan.MessageMan.DebugDia("Error getting image", e); // Create a response ImageManagerResponseEventArgs response = new ImageManagerResponseEventArgs() { Request = currentRequest.Context, Success = false }; // Send the response currentRequest.Context.m_onRequestComplete.Raise(currentRequest.Context, response); } // Once we are done, check to see if there is another we should service. lock (m_requestList) { // Remove the current request. m_requestList.Remove(currentRequest); // Kill the current request currentRequest = null; // Check if there is another request we should service now. for (int i = 0; i < MAX_RUNNING_IMAGE_REQUESTS; i++) { if (m_requestList.Count > i && !m_requestList[i].isServicing) { currentRequest = m_requestList[i]; currentRequest.isServicing = true; break; } } } } }