Skip to main content
 首页 » 编程设计

c#之单体机器人 : Intermittent failure when reading a large json string from web service

2024年01月11日31freeliver54

我在线程上使用下面的代码(在 ui 中显示进度对话框)从 ASP.Net MVC web 服务读取 json 字符串。数据可以在 1 mb 到 4 mb 之间。

    public static class WebRequestEx 
    { 
        public static string ExecuteRequestReadToEnd(this WebRequest req) 
        { 
            var resp = req.GetResponse(); 
            using (var resps = resp.GetResponseStream()) 
            { 
                StringBuilder sb = new StringBuilder(); 
                // read through the stream loading up the string builder 
                using (var respRdr = new StreamReader(resps)) 
                { 
                    //return respRdr.ReadToEnd(); 
                    while (!respRdr.EndOfStream) 
                    { 
                        sb.Append(respRdr.ReadLine()); 
                    } 
                    return sb.ToString(); 
                } 
            } 
        } 
} 

堆栈跟踪如下。

I/mono    (15666): Stacktrace: 
I/mono    (15666): 
I/mono    (15666):   at System.Threading.WaitHandle.set_Handle (intptr) <0x0008b> 
I/mono    (15666):   at System.Threading.EventWaitHandle..ctor (bool,System.Threading.EventResetMode) <0x00053> 
I/mono    (15666):   at System.Threading.ManualResetEvent..ctor (bool) <0x0001f> 
I/mono    (15666):   at (wrapper remoting-invoke-with-check) System.Threading.ManualResetEvent..ctor (bool) <0xffffffff> 
I/mono    (15666):   at System.Net.WebAsyncResult.get_AsyncWaitHandle () <0x00073> 
I/mono    (15666):   at System.Net.WebAsyncResult.WaitUntilComplete (int,bool) <0x00033> 
I/mono    (15666):   at System.Net.WebConnectionStream.Read (byte[],int,int) <0x000b3> 
I/mono    (15666):   at System.IO.StreamReader.ReadBuffer () <0x00047> 
I/mono    (15666):   at System.IO.StreamReader.ReadLine () <0x0014b> 
I/mono    (15666):   at System.WebRequestEx.ExecuteRequestReadToEnd (System.Net.WebRequest) <0x000ab> 

问题是这种情况不会每次都发生,而且是间歇性的。这很糟糕,因为它会导致整个应用程序卡住并且进度对话框卡住,用户无法对应用程序执行任何操作。我在调用代码中确实有一个 try/catch block ,但这个异常似乎绕过了它。

我之前使用的是 ReadToEnd,它也会间歇性地爆炸,所以我转而逐行阅读。

堆栈跟踪不是特别有用,因为 Readline() 中似乎正在发生某些事情。

想法/建议/替代方案?

请您参考如下方法:

除非您对 WebRequest 有特殊要求,否则您应该使用 WebClient .

类似DownloadString 的方法和(甚至更好)DownloadStringAsync将使您免于处理响应位,在响应位中很容易将方式分配给会影响您的应用程序性能的大量内存和临时字符串。