Proper placement of WebRequest and StreamReader

I get an exception for an object when I call the ReadToEnd method from a client-side method, getRecords, which communicates with a web server using StreamReader.

The first call to getRecords succeeds, only during the next call does an exception occur, and therefore I do not close and dispose of the StreamReader and the associated WebRequest properly.

I know that I could wrap these two objects in a using statement, however this just expanded into a try / catch / finally statement. As you can see from my code below, I clean up my final sentence.

Therefore, I either do not do something that uses the statment used, or there is something else that I can lose in my final status. . I would prefer not to use the statment used, if anything is possible, since I like my code.

Here is the code and the exception associated with it:

public int getRecords(string[] args, string[] vals) { List<string> urlList = BuildUrlRequestStrings(args, vals); WebRequest request = null; WebResponse wresponse = null; StreamReader sr = null; foreach (string url in urlList) { request = WebRequest.Create(url); request.Method = "GET"; request.ContentType = "application/json"; //request.Timeout = -1; request.Timeout = 300000; request.Credentials = CredentialCache.DefaultCredentials; //request.ContentType = "application/xml"; try { wresponse = request.GetResponse(); /*using (StreamReader sr = new StreamReader(wresponse.GetResponseStream())) { _recieveBuffer = sr.ReadToEnd().ToString(); }*/ sr = new StreamReader(wresponse.GetResponseStream()); _recieveBuffer = sr.ReadToEnd(); //List<T> temp = JsonConvert.DeserializeObject<List<T>>(_recieveBuffer); List<T> temp = JsonConvert.DeserializeObject<List<T>>( _recieveBuffer, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All } ); _recieveData.AddRange(temp); } catch (WebException ex) { if (ex.Response != null) { // can use ex.Response.Status, .StatusDescription if (ex.Response.ContentLength != 0) { using (var stream = ex.Response.GetResponseStream()) { using (var reader = new StreamReader(stream)) { Log.Info(FIDB.TAG1, " WSBuffer.getRecords: WEBSERVER MESSAGE: " + reader.ReadToEnd()); } } } } return -1; } finally { if (sr != null) { sr.Close(); sr.Dispose(); } if (wresponse != null) { wresponse.Close(); wresponse.Dispose(); } } } return _recieveData.Count; } 

07-02 11: 32: 15.076: I / <FI β†’> (2775): StorageRelayService.RequestQueueThread: EXCEPTION: System.ObjectDisposedException: the object was used after it was located. 07-02 11: 32: 15.076: I / <FI β†’> (2775): with System.Net.WebConnection.BeginRead (request System.Net.HttpWebRequest, Buffer System.Byte [], offset Int32, size Int32, System. AsyncCallback cb, System.Object state) [0x00000] at: 0 07-02 11: 32: 15.076: I / <FI β†’> (2775): with System.Net.WebConnectionStream.BeginRead (buffer System.Byte [], Int32 offset, Int32 size, System.AsyncCallback cb, System.Object state) [0x00000] in: 0 07-02 11: 32: 15.076: I / <FI

(2775): in System.Net.WebConnectionStream.Read (buffer System.Byte [], offset Int32, size Int32) [0x00000] at: 0 07-02 11: 32: 15.076: I / <FI β†’> (2775) : with System.IO.StreamReader.ReadBuffer () [0x00000] at: 0 07-02 11: 32: 15.076: I / <FI β†’> (2775): with System.IO.StreamReader.Read (buffer System.Char [ ], index Int32, Int32 count) [0x00000] in: 0 07-02 11: 32: 15.076: I / <FI (2775): in System.IO.StreamReader.ReadToEnd () [0x00000] in: 0 07-02 11: 32: 15.076: I / <<FI β†’> (2775): with FieldInspection.Shared.Buffer.WSBuffer 1[FieldInspection.Shared.Model.AggregateRoot.Parcel].getRecords (System.String[] args, System.String[] vals) [0x00000] in <filename unknown>:0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Shared.Repository.REST.RepositoryREST 1 [FieldInspection. Shared.Model.AggregateRoot.Parcel] .read (Terms and Conditions) [0x00000] at: 0 07-02 11: 32: 15.076: I / <FI β†’> (2775): when FieldInspection.Shared.Model.DataAccess.ParcelRepositoryREST.parcelByIdList (System.Collections.Generic.List 1 parcelIdList, Boolean bCurrent, Boolean bHistorical) [0x00000] in <filename unknown>:0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Droid.StorageRelayService.ProcessRequestGetParcelCache (FieldInspection.Shared.Database.IPC.Request request) [0x00000] in <filename unknown>:0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Droid.StorageRelayService.ProcessRequestFromForegroundActivity (System.Collections.Generic.List 1 reqList) [0x00000] in: 0 07-02 11: 32: 15.076 : I / <<FI β†’> (2775): when FieldInspection.Droid.StorageRelayService.RequestQueueThread () [0x00000] at: 0

+7
source share
4 answers

Use using , which closes your connection if it loses scope.

-2
source

I highly recommend you use the "using" statement. Once you know that your WebResponse and StreamReader are located correctly, it becomes easier to debug.

In addition, you create a WebRequest object for each iteration of the loop. Why don't you try the asynchronous approach?

This post may be useful: How to use HttpWebRequest (.NET) asynchronously?

+2
source

I know you already accepted the answer, but an alternative solution would be to place variable declarations inside the foreach .

 foreach (string url in urlList) { WebRequest request = null; WebResponse wresponse = null; StreamReader sr = null; ... } 

Then each loop will get its own instance, and .Dispose() will work as you expect.

+1
source

If your first run is fine and you are having trouble with the following queues, so it’s most likely because the garbage collector hasn’t cleared the closed objects. Do the following at the end of the finally block.

 GC.Collect(); GC.WaitForPendingFinalizers(); 
0
source

All Articles