使用StreamReader和HttpWebResponse块ReadToEnd()

时间:2016-04-14 16:24:53

标签: c# httpwebrequest windows-mobile compact-framework streamreader

我有一个适用于Windows Mobile 6.5终端的CSharp应用程序(CF2.0)。 我有一个线程,每1.5分钟尝试连接到一个PHP WebService。我尝试使用ReadToEnd()方法读取此PHP WebService的响应。 它有效,但有时(随机)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§

当Block出现时,在我的日志中,我看到“lsp_r2:inizio a leggere”(ReadToEnd之前的行),我没有看到 lsp_r2:terminato di leggere (ReadToEnd之后的行)。

我也尝试过使用类似的东西

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 Communication可以阻止读取?我应该使用 ReadLine ,因为该行以CRLF结尾?我是否必须使用其他一些方法?

抱歉我的英文。如果我必须提供其他一些信息,请告诉我。

TIA

的Alessandro

1 个答案:

答案 0 :(得分:0)

以下是有关如何使用线程和外部超时(第二个线程)执行此操作的未经检查的代码段:

using System;
using System.Web;
using System.Threading;

public class myWebRequest:IDisposable{
    public class myEventArgs:System.EventArgs{
        public string msg;
        public myEventArgs(string s){
            msg=s;
        }
    }
    public delegate void myDelegate (myEventArgs args);

        public myDelegate theDelegate;

        void onUpdate (myEventArgs arg)
        {
            if (theDelegate != null)
                theDelegate (arg);
        }

        Thread myThread = null;
        Thread watchThread = null;

    object lockObject = new object ();
    bool bThreadRunning = false;

    public myWebRequest(){
    }
    public void Dispose(){
        if (watchThread != null) {
            watchThread.Abort ();
            watchThread = null;
        }
        if (myThread != null) {
            myThread.Abort ();
            myThread = null;
        }
    }

    public void startRequest(){
        if (myThread != null) {
            myThread.Abort ();
            myThread = null;
        }
        myThread = new Thread (theThread);
        myThread.Start ();

        //start the watch thread
        if (watchThread != null) {
            watchThread.Abort ();
            watchThread = null;
        }
        watchThread = new Thread (theWatchThread);
        watchThread.Start ();
    }

    void theWatchThread(){
        try{
            Thread.Sleep (5000);
            if (bThreadRunning && myThread != null) {
                //thread is running, try a join
                if (myThread.Join (5000)) {
                    //join did work, although thread should have finished
                    myThread.Abort ();
                    myThread = null;
                    bThreadRunning = false;
                    onUpdate(new myEventArgs("failed"));
                }
            }
        }catch(ThreadAbortException ex){
        }
        catch(Exception ex){
        }
    }

    void theThread(){
        string sMsg = "";
        try {
            bThreadRunning=true;
            //call the possibly blocking function
            sMsg=myWebRequest.CallWebServiceProblem("url", 4000);
            onUpdate(new myEventArgs(sMsg));
        }catch(ThreadAbortException ex){

        }
        catch (Exception ex) {

        }
        bThreadRunning = false;
    }

    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;

    }
}

从表格中使用它:

    void doTest(){
        myWebRequest theRequest = new myWebRequest ();
        theRequest.theDelegate += new myWebRequest.myDelegate (onReceive);
    }
    void onReceive(myWebRequest.myEventArgs args){
        //updateGUI?
    }

在onReceive中,您将获得“失败”或结果。

以上代码只是一个骨架...