Ich habe eine CSharp-Anwendung (CF2.0) für Windows Mobile 6.5-Terminals. Ich habe einen Thread, der alle 1,5 Minuten versucht, sich mit einem PHP WebService zu verbinden. Ich versuche, die Antwort dieses PHP WebService mit einer ReadToEnd() Methode zu lesen. Es funktioniert, aber manchmal (zufällig) blockiert die Routine auf ReadToEnd(). Ich weiß nicht warum.Verwenden Sie StreamReader mit HttpWebResponse Block ReadToEnd()
Dies ist der Code:
public static string CallWebServiceProblem(string url, int timeout)
{
string s = "";
ServicePointManager.DefaultConnectionLimit = 10;
_logger.Trace("web service: {0} timeout: {1}", url, timeout);
HttpWebRequest wrGETURL = null;
try
{
bool isProblema = url.IndexOf("lsp_r2") >= 0;
if (isProblema)
_logger.Info("Sono in lsp_r2...");
wrGETURL = (HttpWebRequest)WebRequest.Create(url);
wrGETURL.Credentials = CredentialCache.DefaultCredentials;
wrGETURL.ReadWriteTimeout = 10000; // Per vedere se sistema un po' i timeout...
if (timeout != 0)
wrGETURL.Timeout = 3000; // timeout...
Stream ojstream = null;
StreamReader sr = null;
HttpWebResponse httpresponse = null;
try
{
if (isProblema)
_logger.Info("lsp_r2: Chiamo GetResponse...");
httpresponse = (HttpWebResponse)wrGETURL.GetResponse();
if (isProblema)
_logger.Info("lsp_r2: Chiamo GetResponseStream...");
ojstream = httpresponse.GetResponseStream();
Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
if (isProblema)
_logger.Info("lsp_r2: Chiamo StreamReader...");
sr = new StreamReader(ojstream, encode);
if (isProblema)
_logger.Info("lsp_r2: inizio a leggere");
s = sr.ReadToEnd();
if (isProblema)
{
_logger.Info("lsp_r2: terminato di leggere " + s.Length + " caratteri");
System.Diagnostics.Debug.WriteLine("lsp_r2: terminato di leggere " + s.Length + " caratteri");
#if DEBUG
// _logger.Info("lsp_r2: ho letto " + s);
System.Diagnostics.Debug.WriteLine("lsp_r2: ho letto " + s);
#endif
}
}
catch (Exception ex)
{
_logger.Error("web service: {0} timeout: {1} exception: {2} - {3}", url, timeout, ex.Message, ex.InnerException != null ? ex.InnerException.Message : "??");
throw new Exception(ex.Message);
}
finally
{
if (isProblema)
_logger.Info("lsp_r2: Concludo...");
if (sr != null)
{
sr.Close();
sr.Dispose();
}
if (ojstream != null)
{
ojstream.Close();
ojstream.Dispose();
}
if (httpresponse != null)
{
httpresponse.Close();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
}
return s;
}
ich diese Routine für einige PHP WS in meiner Anwendung verwenden, aber ich habe das Problem nur mit einem, der eine Menge von Zeichen zurückgibt (kann 8000 und mehr .. .). Die von WS zurückgegebene Zeichenfolge ist eine Zeichenfolge, die mit CRLF endet. Werte werden mit | getrennt und Datensätze werden mit § getrennt (können diese ASCII Zeichen ein Problem sein ??). So etwas (dieses Beispiel hat nur einen Datensatz)
80643 | 882168 | 145 | 1 | 3 | 1 | 0 | 0 | 0 | 0 | 0 | 2016-04-04 19: 43: 24 | 1900- 01-01 00: 00: 00 | 1900-01-01 00: 00: 00 | 1900-01-01 00: 00: 00 | 2016-04-04 19: 43: 42 ||||| 2016-04- 04 09: 45: 42 | 08: 45 1TG GALDINO, 8 Mailand Ditta: ZEBRE X PROVA() || Int.pr: Orario Continuato | 2016-04-04 10: 45: 42 | V LARGA, Ditta:() | LARGA | Int.co: Orario Continuato || 0 | 2016-04-04 08: 46: 03 | 2016-04-04 19: 43: 42 | 2 || 0 | 0000-00-00 00: 00: 00§
Wenn der Block occours, in meinem log ich sehe "lsp_r2: inizio ein leggere" (die Zeile vor dem ReadToEnd) und ich sehe nicht, lsp_r2: terminato di leggere (die Zeile nach der ReadToEnd) .
Ich habe auch versucht, so etwas wie diese
int totCar = 0;
while (sr.EndOfStream == false) {
int numCar = sr.Peek();
char[] caratteri = new char[numCar];
sr.Read(caratteri, 0, numCar);
string newString = new string(caratteri);
// Arrivano un sacco di null.. li rimuovo
int posNull = newString.IndexOf('\0');
if (posNull >= 0)
newString = newString.Substring(0, posNull);
s += newString;
totCar += newString.Length;
// if (isProblema)
// _logger.Info("lsp_r2: letti: " + numCar + " caratteri");
}
mit Aber ich habe auch sr.Read
Es ist etwas, ich weiß nicht, über die Socket-Kommunikation habe Problem mit, dass der Block Gelesen? Sollte ich eine ReadLine verwenden, weil die Linie mit CRLF endet? Muss ich andere Methoden verwenden?
Entschuldigung für mein Englisch. Lassen Sie es mich wissen, wenn ich weitere Informationen geben muss.
TIA
Alessandro
Nicht nur die Anfrage/lesen kann blockieren, auch asynchrone WebRequest kann fehlschlagen. Die Ursache kann ein getrenntes Netzwerk und viele andere sein (Sie müssen Netzwerk-Traces und Server-Ereignisprotokolle analysieren). Ich würde Ihren Code in einen neuen Thread einfügen und dann thread.join nach dem Timeout verwenden, um zu testen, ob der Thread fertig ist. Wenn die Anfrage nicht erfolgreich war, können Sie den Thread erneut versuchen. – josef
Danke @josef hast du ein Beispiel, wie man das umsetzt? Von welcher Auszeit sprichst du? –