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

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

C# crifan 8816浏览 0评论

【问题】

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 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;
}

中的:

1
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就可以了。

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

1
2
3
4
5
6
7
8
9
10
11
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中获得值

去改动代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 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,无法访问已关闭的流
            //System.ObjectDisposedException
            respHtml = "";
        }
    }
 
    return respHtml;
}

希望对以后有效果。

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

 

【总结】

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

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

发表我的评论
取消评论

表情

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

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