正确处理WebRequest和StreamReader

时间:2012-12-24 16:46:57

标签: c# .net web-services httpwebrequest

在从客户端方法getRecords调用ReadToEnd方法期间,我得到一个对象处理异常,该方法使用StreamReader与Web服务器通信。

第一次调用getRecords成功,只是在后续调用期间发生异常,所以我没有关闭并正确处理StreamReader和关联的WebRequest。

我知道我可以将这两个对象包装在using语句中,但是这只会扩展为try / catch / finally语句。从下面的代码中可以看出,我正在清理我的finally子句。

因此,我要么不做使用陈述所做的事情,要么在我的最终陈述中还有其他一些我可能会遗漏的东西。我宁愿不使用使用陈述,如果在一切皆有可能,因为我喜欢我的代码。

以下是代码和相关的异常:

    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 /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):   StorageRelayService.RequestQueueThread:EXCEPTION:   System.ObjectDisposedException:该对象在被使用后使用   处置。 07-02 11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at   System.Net.WebConnection.BeginRead(System.Net.HttpWebRequest请求,   System.Byte []缓冲区,Int32偏移量,Int32大小,System.AsyncCallback   cb,System.Object state)[0x00000] in:0 07-02   11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at   System.Net.WebConnectionStream.BeginRead(System.Byte [] buffer,Int32   offset,Int32 size,System.AsyncCallback cb,System.Object state)   [0x00000] in:0 07-02 11:32:15.076:I /&lt;&lt;&lt; FI

     
    
      
        

(2775):在System.Net.WebConnectionStream.Read(System.Byte []缓冲区,Int32偏移量,Int32大小)[0x00000] in:0         07-02 11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at         System.IO.StreamReader.ReadBuffer()[0x00000] in:0         07-02 11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at         System.IO.StreamReader.Read(System.Char [] buffer,Int32 index,Int32         count)[0x00000] in:0 07-02 11:32:15.076:I /&lt;&lt;&lt; FI         (2775):在System.IO.StreamReader.ReadToEnd()[0x00000] in:0 07-02 11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at         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         (IConditions条件)[0x00000] in:0 07-02         11:32:15.076:I /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at         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 /&lt;&lt;&lt; FI&gt;&gt;&gt;(2775):at         FieldInspection.Droid.StorageRelayService.RequestQueueThread()         [0x00000] in:0

      
    
  

4 个答案:

答案 0 :(得分:2)

我强烈建议您使用“使用”声明。一旦您知道WebResponse和StreamReader正确处理,就可以更容易地进行调试。

此外,您为循环的每次迭代创建一个WebRequest对象。你为什么不尝试一种不经常的方法呢?

这篇文章可能会有所帮助:How to use HttpWebRequest (.NET) asynchronously?

答案 1 :(得分:1)

我知道您已经接受了答案,但另一种解决方案是将变量声明置于 foreach循环中。

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

然后每个循环将获得它自己的实例,.Dispose()将按预期工作。

答案 2 :(得分:0)

如果您的第一次运行正常并且您在下次运行时遇到问题,那么很可能是因为垃圾收集器没有清理关闭的对象。在finally阻止结束时执行以下操作。

GC.Collect();
GC.WaitForPendingFinalizers();

答案 3 :(得分:-2)

利用using一旦失去范围就会关闭你的连接。