Perché questo codice si blocca raggiungendo il primo ReadLine da uno StreamReader?

Stavo passando un file di grandi dimensioni nel primo argomento a SendXMLFile () di seguito ma, poiché causava il blocco del dispositivo palmare / “congelamento”, ho temporaneamente codificato un file molto più piccolo (3 KB anziché 1121 KB) per il test.

Il file esiste davvero (nella stessa cartella di .exe / .dll), come può essere visto da questo codice:

// 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); 

Ecco il codice che viene poi chiamato, tentando di inviare il file:

 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"); } . . . 

Quando eseguo questo, vedo:

 "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" 

– ma non il messaggio ” line == … ” – si blocca, e devo scaldare il dispositivo per riportarlo dal limbo elettronico.

C’è un potenziale problema con il codice StreamReader o … ???

AGGIORNARE

Non so se questo sia un problema sia nei dati, sia nelle differenze che dovevo fare nel codice per farlo funzionare nel Compact Framework. Ho un codice molto simile che funziona da un’app 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; } } } 

— chiamato così, passando lo stesso file di un caso di test:

 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); } 

AGGIORNAMENTO 2

Ho cambiato il codice per usare un XMLTextReader, e ora sono tornato all’errore che avevo in precedenza, vale a dire “(400) Bad Request” che è documentato nella maggior parte dei suoi dettagli cruenti qui .

Ecco il nuovo codice e quello che ora vedo:

public static bool WriteIt2 (string fileName, string data, long fsize) {bool retVal = false; int bytRd = 0; // se lo usi, cambia il suo nome string 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); 

Ora ecco il codice che effettivamente legge, scrive e invia (o prova a):

 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; } } 

Quello che vedo ora quando corre:

 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" 

Quindi almeno non è più sospeso, ma sono tornato a chiedermi perché il server considera questa una ctriggers richiesta.

Penso che dovresti tornare alle origini:

 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); } } 

e vedere cosa funziona e cosa pensa il server del tuo file.

Quando hai veramente bisogno di un TimeOut allora vedi questa risposta