最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【未解决】C#中StreamReader中遇到异常:未处理ObjectDisposedException,无法访问已关闭的流

C# crifan 8680浏览 0评论

【问题】

测试一个C#,结果其中这部分代码:

    // valid charset:"GB18030"/"UTF-8", invliad:"UTF8"
    public string getUrlRespHtml(string url,
                                    Dictionary<string, string> headerDict,
                                    string charset,
                                    Dictionary<string, string> postDict,
                                    int timeout,
                                    string postDataStr)
    {
        string respHtml = "";

        //HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout);
        HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout, postDataStr);

        //long realRespLen = resp.ContentLength;
        if (resp != null)
        {
            StreamReader sr;
            if ((charset != null) && (charset != ""))
            {
                Encoding htmlEncoding = Encoding.GetEncoding(charset);
                sr = new StreamReader(resp.GetResponseStream(), htmlEncoding);
            }
            else
            {
                sr = new StreamReader(resp.GetResponseStream());
            }
            
            //respHtml = sr.ReadToEnd();
            while (!sr.EndOfStream)
            {
                respHtml = respHtml + sr.ReadLine();
            }

            sr.Close();

            resp.Close();
        }

        return respHtml;
    }

中的:

respHtml = respHtml + sr.ReadLine();

出错:

未处理ObjectDisposedException

无法访问已关闭的流

 

unhandled ObjectDisposedException

异常的详细信息是:

未处理 System.ObjectDisposedException

  Message=无法访问已关闭的流。

  Source=System

  ObjectName=""

  StackTrace:

       在 System.Net.GZipWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 size)

       在 System.IO.StreamReader.ReadBuffer()

       在 System.IO.StreamReader.ReadLine()

       在 crifanLib.getUrlRespHtml(String url, Dictionary`2 headerDict, String charset, Dictionary`2 postDict, Int32 timeout, String postDataStr) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\libs\crifan\crifanLib.cs:行号 1717

       在 crifanLib.getUrlRespHtml_multiTry(String url, Dictionary`2 headerDict, String charset, Dictionary`2 postDict, Int32 timeout, String postDataStr, Int32 maxTryNum) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\libs\crifan\crifanLib.cs:行号 1741

       在 crifanLibAmazon.extractAllSingleTypeSellerInfo(String singleTypeUrl) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\libs\crifan\crifanLibAmazon.cs:行号 1142

       在 crifanLibAmazon.extractAllSellerInfo(String usedAndNewUrl, List`1& allSellerInfoList) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\libs\crifan\crifanLibAmazon.cs:行号 1266

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.awsGetAllProductInfo(String itemAsin, awsItemAttributes itemAttributes) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2659

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.awsFindAndSaveItem(String itemAsin, awsItemAttributes itemAttributes) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2401

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.processAmazonItem(String itemAsin) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2385

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.processAwsSearchItem(awsSearchResultItem singleAwsSearchItem) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2188

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.searchSingleBrowseNodeId(String curBrowseNodeId, String curSearchIndex, String curFullCategoryName) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2028

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.doSearchForAllChildOfSingleTreeNode(TreeNode curTreeNode) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2107

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.doSearchForAllChildOfSingleTreeNode(TreeNode curTreeNode) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2098

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.doSearchForAllChildOfSingleTreeNode(TreeNode curTreeNode) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2098

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.awsCategorySearch() 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 2143

       在 ScrapeAmazonProduct.frmScrapeAmazonProduct.btnSearch_Click(Object sender, EventArgs e) 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\frmScrapeAmazonProduct.cs:行号 1590

       在 System.Windows.Forms.Control.OnClick(EventArgs e)

       在 System.Windows.Forms.Button.OnClick(EventArgs e)

       在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)

       在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)

       在 System.Windows.Forms.Control.WndProc(Message& m)

       在 System.Windows.Forms.ButtonBase.WndProc(Message& m)

       在 System.Windows.Forms.Button.WndProc(Message& m)

       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)

       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)

       在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

       在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)

       在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)

       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)

       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)

       在 System.Windows.Forms.Application.Run(Form mainForm)

       在 ScrapeAmazonProduct.Program.Main() 位置 E:\Dev_Root\freelance\Elance\projects\40939187_scrape_amazon\40939187_scrape_amazon\ScrapeAmazonProduct\ScrapeAmazonProduct\Program.cs:行号 17

       在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)

       在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)

       在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()

       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)

       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)

       在 System.Threading.ThreadHelper.ThreadStart()

  InnerException:

 

【解决过程】

1.很明显,代码里面,是先处理StreamReader处理完之后,才会去close的。

但是此处竟然会出现“无法访问已关闭的流”之类的错误,很是匪夷所思。

2.之前也没出现过类似的错误。

3.再去看了看,结果是:

EndOfStream引发了System.ObjectDisposedException类型的异常

endofstream cause the exception

 

4.此人:

C# ftp download and stream to XML error

说是自己加上了keepalive就可以了。

但是我之前的代码,一直是:

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

        req.AllowAutoRedirect = true;
        req.Accept = "*/*";

        //req.ContentType = "text/plain";

        //const string gAcceptLanguage = "en-US"; // zh-CN/en-US
        //req.Headers["Accept-Language"] = gAcceptLanguage;

        req.KeepAlive = true;

的,并且这部分代码,也运行了成千上万次了,一直没出现这样的错误。

不知道此处,为何出错。

5.猜测是:

此时,特定的url:

http://www.amazon.com/gp/offer-listing/B004W8Z3IK/sr=/qid=/ref=olp_page_next?ie=UTF8&colid=&coliid=&condition=new&me=&qid=&shipPromoFilter=0&sort=sip&sr=&startIndex=10

请求amazon服务器的时候,估计其虽然接收到了keepalive为true,但是不知道何种原因导致其关闭了。

所以后来再去EndOfStream,就异常了。

6.但是,还是参考:

无法从HttpWebResponse中获得值

去改动代码为:

    // valid charset:"GB18030"/"UTF-8", invliad:"UTF8"
    public string getUrlRespHtml(string url,
                                    Dictionary<string, string> headerDict,
                                    string charset,
                                    Dictionary<string, string> postDict,
                                    int timeout,
                                    string postDataStr)
    {
        string respHtml = "";

        //HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout);
        HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout, postDataStr);

        //long realRespLen = resp.ContentLength;
        if (resp != null)
        {
            StreamReader sr;
            Stream respStream = resp.GetResponseStream();
            if ((charset != null) && (charset != ""))
            {
                Encoding htmlEncoding = Encoding.GetEncoding(charset);
                sr = new StreamReader(respStream, htmlEncoding);
            }
            else
            {
                sr = new StreamReader(respStream);
            }

            try
            {
                //respHtml = sr.ReadToEnd();
                while (!sr.EndOfStream)
                {
                    respHtml = respHtml + sr.ReadLine();
                }
                respStream.Close();
                sr.Close();
                resp.Close();
            }
            catch (Exception ex)
            {
                //【未解决】C#中StreamReader中遇到异常:未处理ObjectDisposedException,无法访问已关闭的流
                //https://www.crifan.com/csharp_streamreader_unhandled_exception_objectdisposedexception_cannot_access_closed_stream
                //System.ObjectDisposedException
                respHtml = "";
            }
        }

        return respHtml;
    }

希望对以后有效果。

至少当异常的时候,代码还能继续跑。。。

 

【总结】

至此,还是没有完全搞懂错误的根本原因。

转载请注明:在路上 » 【未解决】C#中StreamReader中遇到异常:未处理ObjectDisposedException,无法访问已关闭的流

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.190 seconds, using 22.14MB memory