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文字で問題ありますか?)。このようなもの(この例ではレコードは1つだけです)
80643 | 882168 | 145 | 1 | 3 | 1 | 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、ミラノ・ディッタ: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 A 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
を使用して問題がありましたをお読みください? ReadLineを使用する必要があります。その行はCRLFで終わっていますか?他の方法を使わなければならないのですか?
私の英語のために残念です。私はいくつかの他の情報を与えなければならないかどうか教えてください。ここ
TIA
アレッサンドロ
要求/読み取りがブロックできるだけでなく、非同期のWebRequestでも失敗する可能性があります。根本的な原因は、切断されたネットワークや他の多くの場合です(ネットワークトレースとサーバーイベントログを分析する必要があります)。あなたのコードを新しいスレッドに入れて、タイムアウト後にthread.joinを使って、スレッドが終了したかどうかをテストします。要求が成功しなかった場合は、スレッドを再試行することができます。 – josef
ありがとう@josefこれを実装する方法の例がありますか?あなたはどのタイムアウトを話していますか? –