正确处理WebRequest和StreamReader



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

对getRecords的第一次调用成功,只有在随后的调用中才会发生异常,因此我没有正确关闭和处置StreamReader和相关的WebRequest。

我知道我可以将这两个对象包装在using语句中,但是这只是扩展为try/catch/finally语句。如下面的代码所示,我在finally子句中进行了清理。

因此,我要么没有做using语句所做的事情,要么在finally语句中遗漏了其他一些事情。如果可能的话,我宁愿不使用using语句,因为我喜欢我的代码显式。

下面是代码和相关的异常:
    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/<<>> (2775):StorageRelayService。RequestQueueThread:例外:系统。ObjectDisposedException:对象被使用后处理。07-02 11:32:15. 06:我/<<>>(2775): atSystem.Net.WebConnection.BeginRead (System.Net。HttpWebRequest请求,系统。Byte[] buffer, Int32偏移量,Int32大小,System。AsyncCallbackcb、系统。对象状态)[0x00000] in:0 07-0211:32:15.076:我/& lt; & lt; & lt;FI>>>(2775): atSystem.Net.WebConnectionStream.BeginRead(系统。Byte[] buffer, Int32offset, Int32大小,System。系统;对象状态)[0x00000] in:0 07-02 11:32:15.076: I/<<

(2775): at System.Net.WebConnectionStream.Read (System. net)Byte[] buffer, Int32 offset, Int32 size) [0x00000] in:007-02 11:32:15. 06:我/<<>>(2775): atSystem.IO.StreamReader.ReadBuffer () [0x00000] in:007-02 11:32:15. 06:我/<<>>(2775): atSystem.IO.StreamReader.Read(系统。Char[] buffer, Int32索引,Int32count) [0x00000] in:0 07-02 11:32:15.076: I/<<>>(2775): atFieldInspection.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(条件条件)[0x00000] in:0 07-0211:32:15.076:我/& lt; & lt; & lt;FI>>>(2775): atFieldInspection.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/<<>>(2775): atFieldInspection.Droid.StorageRelayService.RequestQueueThread ()[0x00000] in:0

我强烈建议您使用"using"语句。一旦你知道你的WebResponse和StreamReader配置正确,它就变得更容易调试。

同样,您为循环的每次迭代创建一个WebRequest对象。为什么不尝试异步方法呢?

这篇文章可能是有帮助的:如何使用HttpWebRequest (.NET)异步?

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

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

然后每个循环将得到它自己的实例,并且.Dispose()将按照您的期望工作。

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

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

使用using,一旦失去作用域,将关闭您的连接

相关内容

  • 没有找到相关文章

最新更新