为什么这段代码会在从StreamReader到达第一个ReadLine时挂起?

我在第一个arg中将一个大文件传递给下面的SendXMLFile(),但由于它导致手持设备“挂起”/“冻结”,我暂时硬编码了一个小得多的文件(3 KB而不是1121 KB)用于检测。

该文件确实存在(与.exe / .dll位于同一文件夹中),如下代码所示:

// test with smaller file: fileName = "DSD_v6666_3_20140310140737916.xml"; MessageBox.Show("Made it before file.Open"); using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew)) { fileTest.Write(info, 0, info.Length); fileTest.Flush(); } if (!File.Exists(fileName)) { MessageBox.Show(String.Format("{0} does not seem to exist", fileName)); } else { MessageBox.Show(String.Format("{0} DOES seem to exist", fileName)); } string justFileName = Path.GetFileNameWithoutExtension(fileName); String uri = String.Format(@"http://SHANNON2:21609/api/inventory/sendXML/gus/woodrow/{0}", justFileName).Trim(); SendXMLFile(fileName, uri, 500); 

这是随后调用的代码,尝试发送文件:

 public static string SendXMLFile(string xmlFilepath, string uri, int timeout) { // TODO: Remove after testing String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout); MessageBox.Show(s); // </ TODO: Remove after testing HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); //request.KeepAlive = false; // should this be true? <== commented out as a test, but no diff in behavior request.ProtocolVersion = HttpVersion.Version10; request.ContentType = "application/xml"; request.Method = "POST"; StringBuilder sb = new StringBuilder(); // TODO: Remove after testing MessageBox.Show("Made it to just before the StreamReader using"); using (StreamReader sr = new StreamReader(xmlFilepath)) { // TODO: Remove after testing MessageBox.Show("Made it just inside the StreamReader using"); // <= This is the last point reached String line; while ((line = sr.ReadLine()) != null) { // TODO: Remove after testing MessageBox.Show(string.Format("line == {0}", line)); sb.Append("\r\n"); } . . . 

当我运行这个时,我看到:

 "Made it before file.Open" "DSD_v6666_3_20140310140737916.xml DOES seem to exist" [The xmlFilepath, uri, and timout vals expected] "Made it to just before the StreamReader using" "Made it just inside the StreamReader using" 

– 但不是“ line == … ”消息 – 它挂起,我必须热启动设备才能从电子设备中恢复。

StreamReader代码是否存在潜在问题,或者…… ???

UPDATE

我不知道数据中是否存在问题,或者我在代码中必须做出的差异才能使其在Compact Framework中工作。 我有一个非常类似的代码,可以在Winforms应用程序中运行:

 public static string SendXMLFile(string xmlFilepath, string uri, int timeout) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.KeepAlive = false; request.ProtocolVersion = HttpVersion.Version10; request.ContentType = "application/xml"; request.Method = "POST"; StringBuilder sb = new StringBuilder(); using (StreamReader sr = new StreamReader(xmlFilepath)) { String line; while ((line = sr.ReadLine()) != null) { sb.AppendLine(line); } byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString()); if (timeout < 0) { request.ReadWriteTimeout = timeout; request.Timeout = timeout; } request.ContentLength = postBytes.Length; try { Stream requestStream = request.GetRequestStream(); requestStream.Write(postBytes, 0, postBytes.Length); requestStream.Close(); //using (var response = (HttpWebResponse)request.GetResponse()) //{ // return response.ToString(); //} // alternate way, safe for older versions of .NET HttpWebResponse response = null; try { response = (HttpWebResponse)request.GetResponse(); } finally { IDisposable disposableResponse = response as IDisposable; if (disposableResponse != null) disposableResponse.Dispose(); } } catch (Exception ex) { MessageBox.Show(ex.Message); request.Abort(); return string.Empty; } } } 

—像这样调用,传递相同的文件作为测试用例:

 private void button20_Click(object sender, EventArgs e) { // Change the file name before each test String fullFilePath = @"C:\HoldingTank\DSD_v6666_3_20140310140737916.xml"; string justFileName = Path.GetFileNameWithoutExtension(fullFilePath); String uri = String.Format(@"http://localhost:21608/api/inventory/sendXML/su/su/{0}", justFileName); SendXMLFile(fullFilePath, uri, 500); } 

更新2

我改变了代码以使用XMLTextReader,现在我又回到了我以前犯过的错误,即“(400)Bad Request”,这里记录了它的大部分细节。

这是新代码,我现在看到的:

public static bool WriteIt2(string fileName,string data,long fsize){bool retVal = false; int bytRd = 0; //如果使用它,请更改其名称字符串the_Msg =“”;

 if (File.Exists(fileName)) { File.Delete(fileName); } Byte[] info = Encoding.UTF8.GetBytes(data); // Testing with this relatively small file for now fileName = "DSD_v6666_3_20140310140737916.xml"; MessageBox.Show("Made it before file.Open"); using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew)) { fileTest.Write(info, 0, info.Length); fileTest.Flush(); } if (!File.Exists(fileName)) { MessageBox.Show(String.Format("{0} does not seem to exist", fileName)); } // I have never seen the msg above, but always saw the one below, so commented it out else //<= always exists, so unnecessary { MessageBox.Show(String.Format("{0} DOES seem to exist", fileName)); } string justFileName = Path.GetFileNameWithoutExtension(fileName); String uri = String.Format(@"http://SHANNON2:21609/api/inventory/sendXML/su/su/{0}", justFileName).Trim(); SendXMLFile(fileName, uri, 500); 

现在这里是实际执行读取,写入和发送(或尝试)的代码:

 public static string SendXMLFile(string xmlFilepath, string uri, int timeout) { String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout); MessageBox.Show(s); // </ TODO: Remove after testing HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); request.ProtocolVersion = HttpVersion.Version10; request.ContentType = "application/xml"; request.Method = "POST"; StringBuilder sb = new StringBuilder(); MessageBox.Show("Made it to just before the StreamReader using"); StreamReader sr = new StreamReader(xmlFilepath); MessageBox.Show("Made it past the StreamReader being constructed"); XmlTextReader reader = null; reader = new XmlTextReader(sr); while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: // The node is an Element. sb.Append(""); sb.Append(">"); break; case XmlNodeType.Text: //Display the text in each element. sb.Append (reader.Value); break; case XmlNodeType. EndElement: //Display end of element. sb.Append(""); break; } } // TODO: Remove after testing MessageBox.Show("Made it past the while loop"); MessageBox.Show(String.Format("sb first line is {0}", sb[0].ToString())); MessageBox.Show(String.Format("sb tenth line is {0}", sb[9].ToString())); byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString()); if (timeout < 0) { request.Timeout = timeout; } request.ContentLength = postBytes.Length; try { Stream requestStream = request.GetRequestStream(); requestStream.Write(postBytes, 0, postBytes.Length); requestStream.Close(); // This code for older versions of .NET from ctacke: HttpWebResponse response = null; try { response = (HttpWebResponse)request.GetResponse(); return response.ToString(); } finally { IDisposable disposableResponse = response as IDisposable; if (disposableResponse != null) disposableResponse.Dispose(); } } catch (Exception ex) { MessageBox.Show(ex.Message); request.Abort(); return string.Empty; } } 

这个运行时我现在看到的是什么:

 0) "Made it before file.Open" 1) "DSD_v6666_3_20140310140737916.xml DOES seem to exist" 2) [ the xmlFilePath and other args - they are what is expected ] 3) "Made it to just before the StreamReader using" 4) "Made it past the StreamReader being constructed 5) "Made it past the while loop 6) "sb first line is "" 8) "The remote server returned an error (400) Bad Request" 

所以至少它不再悬挂,但我又想知道为什么服务器认为这是一个糟糕的请求。

我想你应该回归基础:

 public static string SendXMLFile(string xmlFilepath, string uri, int timeout) { using (var client = new WebClient()) { client.Headers.Add("Content-Type", "application/xml"); byte[] response = client.UploadFile(uri, "POST", xmlFilepath); return Encoding.ASCII.GetString(response); } } 

并查看什么有效以及服务器对您的文件的看法。

当你真的需要TimeOut然后看到这个答案