protected void SetTexture(Texture2D tex) { lock (this) { //Trace.WriteLine("SetTexture: " + this.Filename.ToString()); if (IsDisposed && tex != null) { tex.Dispose(); Global.RemoveTexture(tex); tex = null; } if (BodyRequestState != null) { this.BodyRequestState.Dispose(); this.BodyRequestState = null; } this._Result = tex; this.FinishedReading = true; graphicsDevice = null; if(!IsDisposed) DoneEvent.Set(); } }
private void HandleWebResponse(HttpWebResponse response) { lock (this) { //Trace.WriteLine("HandleWebResponse on thread #" + Thread.CurrentThread.ManagedThreadId.ToString()); if (response == null) { this.SetTexture(null); return; } if (response.StatusCode == HttpStatusCode.NotFound) { this.TextureNotFound = true; } else if (response.StatusCode != HttpStatusCode.OK) { this.SetTexture(null); return; } if (Aborted || IsDisposed) { if (BodyRequestState != null) { //Trace.WriteLine("Ignoring EndGetServerResponse response for: " + this.Filename.ToString()); BodyRequestState.Dispose(); BodyRequestState = null; return; } } try { //AsyncState state = this.BodyRequestState; //new AsyncState(this.Filename.ToString()); //state.response = response; //state.databuffer = new byte[response.ContentLength]; //state.responseStream = response.GetResponseStream(); //BodyRequestState.response = response; //Stream stream = response.GetResponseStream(); //BodyRequestState.databuffer = new byte[response.ContentLength]; //BodyRequestState.responseStream = response.GetResponseStream(); //I tried very hard to make async reads of the server response work. Unfortunately it always resulted in an access violation. Data is now read synchronously. //state.responseStream.BeginRead(state.databuffer, 0, (int)state.ReadRequestSize(), new AsyncCallback(this.EndReadResponseStream), state); //Byte[] data = state.databuffer; Byte[] data = new byte[response.ContentLength]; using (Stream stream = response.GetResponseStream()) { Debug.Assert(stream != null); if (stream == null) { this.SetTexture(null); return; } int BytesRead = 0; while (BytesRead < response.ContentLength) { BytesRead += stream.Read(data, BytesRead, (data.Length - BytesRead)); } } if (CacheFilename != null) { Action<String, byte[]> AddToCache = Global.TextureCache.AddAsync; AddToCache.BeginInvoke(CacheFilename, data, null, null); } //state.Dispose(); TextureFromStreamAsync(graphicsDevice, data); } catch (WebException e) { ProcessTextureWebException(e, BodyRequestState); } catch (InvalidOperationException e) { //TODO: There is an interaction with aborting requests where an corrupt version of the image ends up in the cache and continues to be used. I have to //figure out how to flush that bad image out of the cache if this occurs. Currently the workaround is to never cache images //Trace.WriteLine(e.Message, "TextureUse"); this.SetTexture(null); } catch (Exception e) { //Trace.WriteLine("Unanticipated exception loading texture: " + requestState.request.RequestUri.ToString(), "TextureUse"); //Trace.WriteLine(e.Message, "TextureUse"); this.SetTexture(null); } } }
protected virtual void Dispose(bool disposing) { lock (this) { //Trace.WriteLine("Dispose TextureReader: " + this.Filename.ToString()); IsDisposed = true; //Debug.Assert(_Result == null); if (_Result != null) { _Result.Dispose(); _Result = null; } //Abort the request if we haven't already if (BodyRequestState != null) { if (BodyRequestState.request != null) { try { BodyRequestState.request.Abort(); BodyRequestState = null; } catch (WebException e) { //Trace.WriteLine(e.Message, "TextureReader.Dispose"); } } BodyRequestState.Dispose(); } if (DoneEvent != null) { DoneEvent.Close(); DoneEvent = null; } } #if DEBUG Global.RemoveTextureReader(this); #endif }
public void AbortRequest() { lock (this) { Aborted = true; //Abort the request if we haven't already if (BodyRequestState != null) { if (BodyRequestState.request != null) { try { BodyRequestState.request.Abort(); BodyRequestState = null; } catch (WebException) { //Trace.WriteLine(e.Message, "TextureReader.Dispose"); } } } //In case we have finished loading the texture, but the texture has not been assigned to the tile, //dispose of the texture if (_Result != null) { if (_Result.IsDisposed == false) { DisposeTextureThreadingObj disposeObj = new DisposeTextureThreadingObj(_Result); ThreadPool.QueueUserWorkItem(disposeObj.ThreadPoolCallback); } _Result = null; } } }
private void TryLoadingFromServer(Uri textureUri) { lock (this) { if (Aborted || IsDisposed) return; //Trace.WriteLine("Checking server: " + textureUri.ToString() + " thread #" + Thread.CurrentThread.ManagedThreadId.ToString()); HttpWebRequest bodyRequest = TextureReader.CreateBasicRequest(textureUri); bodyRequest = CreateBasicRequest(textureUri); bodyRequest.CachePolicy = TextureReader.BodyCachePolicy; this.BodyRequestState = new AsyncState(textureUri.ToString()); //For some reason loading from the server using ASync requests often results in an Access Violation. I've resorted to syncronous requests. BodyRequestState.request = bodyRequest; //BodyRequestState.request.BeginGetResponse(new AsyncCallback(EndGetServerResponse), BodyRequestState); try { HttpWebResponse response = bodyRequest.GetResponse() as HttpWebResponse; HandleWebResponse(response); } catch (WebException e) { ProcessTextureWebException(e, BodyRequestState); } } }
/// <summary> /// Set objects texture to Null, records if the server responds with 404 not found, prints helpful error message /// </summary> /// <param name="e"></param> /// <param name="state"></param> private void ProcessTextureWebException(WebException e, AsyncState state) { if (e.Status == WebExceptionStatus.RequestCanceled) { //Trace.WriteLine("Request Cancelled: " + state.request.Address.ToString()); } else { using (HttpWebResponse ErrorResponse = (HttpWebResponse)e.Response) { if (ErrorResponse != null) { //If the server doesn't have the tile write this down so we stop asking... if (ErrorResponse.StatusCode == HttpStatusCode.NotFound) { this.TextureNotFound = true; } else { //Trace.WriteLine("WebException: " + state.request.Address.ToString()); //Trace.WriteLine(ErrorResponse.StatusCode + " : " + ErrorResponse.StatusDescription, "TextureUse"); } } } } this.SetTexture(null); }
private void TryLoadingFromServer(Uri textureUri, string CacheFilename) { lock (this) { if (Aborted || IsDisposed) return; //Trace.WriteLine("Checking server: " + textureUri.ToString() + " thread #" + Thread.CurrentThread.ManagedThreadId.ToString()); HttpWebRequest bodyRequest = TextureReader.CreateBasicRequest(textureUri); bodyRequest = CreateBasicRequest(textureUri); bodyRequest.CachePolicy = TextureReader.BodyCachePolicy; this.BodyRequestState = new AsyncState(textureUri.ToString()); BodyRequestState.request = bodyRequest; BodyRequestState.request.BeginGetResponse(new AsyncCallback(EndGetServerResponse), BodyRequestState); /* try { HttpWebResponse response = bodyRequest.GetResponse() as HttpWebResponse; HandleWebResponse(response); } catch (WebException e) { ProcessTextureWebException(e, BodyRequestState); } */ } }