我有用於Windows Mobile 6.5終端的CSharp應用程序(CF2.0)。 我有一個線程,每1.5分鐘嘗試連接到一個PHP WebService。我嘗試用ReadToEnd()方法讀取此PHP WebService的響應。 它可以工作,但有時(隨機)ReadToEnd()上的例程塊。我不知道爲什麼。使用帶有HttpWebResponse塊的StreamReader塊ReadToEnd()
這是代碼:
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;
}
我在申請使用該程序的一些PHP WS,但我有問題只與一個返回很多的字符(可8000多.. )。從WS返回的字符串是一個以CRLF結尾的字符串;值用|分隔和記錄用§(可以是這個ASCII字符是一個問題??)分開。類似的東西(這個例子只有一條記錄)
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 Milano 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§
當塊occours,在我的日誌我看到「lsp_r2:inizio一個leggere」(在ReadToEnd的前行),我沒有看到lsp_r2:terminato迪leggere(該行的ReadToEnd的AFTER) 。
我曾嘗試使用也像這樣
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");
}
但我也使用sr.Read
有問題,也有一些是我不知道的Socket通信,可以阻止閱讀?我應該使用ReadLine,因爲該行以CRLF結束?我必須使用其他方法嗎?
對不起,我的英語。讓我知道如果我必須提供一些其他信息。
TIA
亞歷山德羅
不僅請求/讀取可以阻塞,甚至異步WebRequest可能會失敗。根本原因可能是斷開的網絡和其他許多網絡(您需要分析網絡跟蹤和服務器事件日誌)。我會把你的代碼放在一個新線程中,然後在超時後使用thread.join來測試線程是否完成。如果請求沒有成功,您可以重新嘗試該線程。 – josef
謝謝@josef你有一個例子如何實現這個?你在說什麼超時? –