1

Webサイトのコンテンツを解析するために、WindowsPhone7マンゴー用のアプリを作成しようとしています。私はなんとかすべてのコードを書くことができましたが、それは戦争地帯のようでした;)。より良い方法でコードを再配置しようとすると、非常に奇妙な問題に直面し始めます。

問題は、プロジェクト内に「MedinetMySchedule」というカスタムクラスを作成し、ブレークポイントを使用してこのクラスをステップスルーする場合です。アプリが最初のメソッドgetrequest()をステップスルーし、数ステップでメインページに戻ってから、2番目のメソッドGetRequestStreamCallback()に戻ることがわかりました。このメインページへのジャンプにより、解析する値がnullの文字列が残ります。次に、3番目のメソッドReadWebRequestCallback()に戻ります。この最後のジャンプでは、デバッグが終了し、電話エミュレーターで何も取得されないため、重要なことは何もありません。MedinetMyScheduleクラスのコードは次のとおりです。-

namespace WindowsPhonePanoramaApplication1
{
    public class MedinetMySchedule
    {

        //Medinet user url
        public string url { get; set; }
        public String myresponse;
        public void getrequest()
        {
            HttpWebRequest request = HttpWebRequest.CreateHttp(url);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.BeginGetRequestStream(GetRequestStreamCallback, request);
        } 

        private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
            {
                string postData = string.Format("username={0}&password={1}&customer=******&doLogin=Logga+in&language=se", "*****", "******");

                // Convert the string into a byte array.
                byte[] data = Encoding.UTF8.GetBytes(postData);


                // Write to the request stream.
                postStream.Write(data, 0, data.Length);
                postStream.Close();
            }

            //Initiating get response
            request.BeginGetResponse(ReadWebRequestCallBack, request);

        }

        private void ReadWebRequestCallBack(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
            WebResponse myResponse = (WebResponse)request.EndGetResponse(asynchronousResult);
                Stream encodingStream = myResponse.GetResponseStream();
                Encoding encode = Encoding.GetEncoding("iso-8859-1");
                using (StreamReader httpwebStreamReader = new StreamReader(encodingStream, encode))
                {
                    myresponse= httpwebStreamReader.ReadToEnd();
                }
                myResponse.Close();
        }
    }
 }

getrequest()を呼び出してコンテンツを解析するコードは次のとおりです。-

            MedinetMySchedule mittschema = new MedinetMySchedule();
        mittschema.url = "https://medinet.se/cgi-bin/doctor.pl?action=login&customer=saskir&language=se";
        mittschema.getrequest();
        Dispatcher.BeginInvoke(() => parseResults(mittschema.myresponse));
        private void parseResults(string myresponse)
    {
        if (string.IsNullOrEmpty(myresponse))
        {
            return;
        }

        //Initiating a listbox and add item to it
        List<MediNetScheme> medinetScheme = new List<MediNetScheme>();
        //Using HtmlAgilityPack to parse the HTMLcode from the response
        HtmlDocument htdoc = new HtmlDocument();
        htdoc.LoadHtml(myresponse);
        foreach (HtmlNode table in htdoc.DocumentNode.SelectNodes("//table[@class='list-medium']/tbody[1]/tr[@class]"))
        {
            //Removing ChildNode
            table.ChildNodes.RemoveAt(3);
            string itemValue = table.InnerText;
            //Changing the parsed date into a DateTime
            string d;
            DateTime datum = DateTime.Parse(itemValue.Remove(11));
            d = datum.ToString("D");
            //Adding items to the listbox
            medinetScheme.Add(new MediNetScheme() { Datum = d, Sections = itemValue.Remove(0, 15) });
        }
        MediNetScheme.ItemsSource = medinetScheme;

    }

なぜこれが起こっているのか、そしてそれを修正する方法はありますか?

あなたの/オマール

4

1 に答える 1

2

前後に実行されるのは、request.BeginGetRequestStreamが非同期であるためです。基本的に、新しいスレッドを作成し、メインコードと並行して実行します。したがって、データのダウンロードが完了する前にparseResultを呼び出すことになります。コードを書き直す方法はたくさんありますが、私のお気に入りはコールバックを使用することです。

まず、コールバックを受け入れるようにgetRequestメソッドを変更し、それを保存します。

    private Action Callback;

    public void getrequest(Action callback)
    {
        this.Callback = callback;
        HttpWebRequest request = HttpWebRequest.CreateHttp(url);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.BeginGetRequestStream(GetRequestStreamCallback, request);
    } 

次に、ReadWebRequestCallbackの最後に、次のコールバックを呼び出します。

    private void ReadWebRequestCallBack(IAsyncResult asynchronousResult)
    {
        HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
        WebResponse myResponse = (WebResponse)request.EndGetResponse(asynchronousResult);
            Stream encodingStream = myResponse.GetResponseStream();
            Encoding encode = Encoding.GetEncoding("iso-8859-1");
            using (StreamReader httpwebStreamReader = new StreamReader(encodingStream, encode))
            {
                myresponse= httpwebStreamReader.ReadToEnd();
            }
            myResponse.Close();

        this.Callback();
    }

最後に、メインページからgetrequestメソッドを呼び出し、コールバックとしてparseResultsを使用するように指示します。

Action callback = () => Dispatcher.BeginInvoke(() => parseResults(mittschema.myresponse));
mittschema.getrequest(callback);
于 2012-05-12T23:32:03.813 に答える