c# - 正确处理 WebRequest 和 StreamReader

标签 c# .net web-services httpwebrequest

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

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

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

因此,我要么没有做 using 语句所做的事情,要么我的 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/<<< FI >>>(2775): StorageRelayService.RequestQueueThread: EXCEPTION: System.ObjectDisposedException: The object was used after being disposed. 07-02 11:32:15.076: I/<<< FI >>>(2775): at System.Net.WebConnection.BeginRead (System.Net.HttpWebRequest request, System.Byte[] buffer, Int32 offset, Int32 size, System.AsyncCallback cb, System.Object state) [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(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/<<< FI

(2775): at System.Net.WebConnectionStream.Read (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(2775): at System.IO.StreamReader.ReadBuffer () [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(2775): at System.IO.StreamReader.Read (System.Char[] buffer, Int32 index, Int32 count) [0x00000] in :0 07-02 11:32:15.076: I/<<< FI (2775): at System.IO.StreamReader.ReadToEnd () [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Shared.Buffer.WSBuffer1[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.RepositoryREST1[FieldInspection.Shared.Model.AggregateRoot.Parcel].Read (IConditions conditions) [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Shared.Model.DataAccess.ParcelRepositoryREST.parcelByIdList (System.Collections.Generic.List1 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.List1 reqList) [0x00000] in :0 07-02 11:32:15.076: I/<<< FI >>>(2775): at FieldInspection.Droid.StorageRelayService.RequestQueueThread () [0x00000] in :0

最佳答案

我强烈建议您使用“using”语句。一旦您知道您的 WebResponse 和 StreamReader 已正确部署,调试就会变得更加容易。

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

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

关于c# - 正确处理 WebRequest 和 StreamReader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14023811/

相关文章:

c# - 在 C# 中创建简单的分层 PSD 文件

c# - WebResource 是空白页

c# - ComboBox 不允许用户使用空值

c# - 当函数属于必须解析的类时,如何向 IServiceCollection 注册委托(delegate)或函数?

c# - 在没有 NETCFSvcUtil 生成代理的情况下与 WCF 的 Compact Framework 通信

.net - 在 .NET 中使用十进制类型的问题

android - 如何将 Android 手机连接到本地服务器上运行的 Web 服务?

c# - 在 c# 中创建一个客户端来调用没有 wsdl 的 web 服务

c# - 显示 Azure BLOB 的上传进度

java - 休息服务 Jax-Rs - 发布多部分/数据