0

Post HTTP Post または Get リクエストの後にオブジェクトを返したいと思います。私はWebアプリケーションで行うことができました。次に、この関数を MS Windows Phone アプリケーションに記述する必要があります。HTTP Get and Post Request の実行に関する記事を読みましたが、まだ理解できません。Web アプリケーションで行ったのと同じように、Web 要求を実行してオブジェクトを返すヘルパー クラスが必要です。私の Windows アプリケーションは MVVM パターンを使用しています。Web リクエストはビューモデルによって呼び出されます。BeginGetResponse をオーバーロードして、IAsyncResult ではなくオブジェクトを返すにはどうすればよいですか? 誰かが私を導くためのリンクまたは例を教えてくれますか? 前もって感謝します。

Web アプリケーションに私の古いコードがあります

public static T GetData<T>(Uri relativeUri)
    {
        var request = CreateRequest(relativeUri);
        HttpWebResponse r;          

        try
        {
            r = (HttpWebResponse)request.GetResponse();                 
            return Deserializer<T>(r.GetResponseStream());
        }
        catch (WebException webex)
        {
            HttpWebResponse webResp = (HttpWebResponse)webex.Response;            
            setSessionError(webResp.GetResponseStream());

        }

        return Deserializer<T>(request.GetResponse().GetResponseStream());
    }


public static T Deserializer<T>(Stream s)
    {
        //Get results   
        var ser = new DataContractSerializer(typeof(T));
        var reader = XmlDictionaryReader.CreateTextReader(s,
            new System.Xml.XmlDictionaryReaderQuotas());
        ser = new DataContractSerializer(typeof(T));
        var deserializedItem = (T)ser.ReadObject(reader, true);
        reader.Close();
        return deserializedItem;
    }

私はそのようなことをしたい:

public static T GetData<T>(Uri relativeUri)
    {
        var request = CreateRequest(relativeUri);
        Stream ResponseStream;
       request.BeginGetResponse(ReadCallback, request, ResponseStream);
       return Deserializer<T>(ResponseStream);
 }
4

2 に答える 2

0

IAsyncResultsを使用せずにそれを行うことはできません。WebClientとHttpWebRequestの2つのオプションがあります...

WebClient wc = new WebClient();
wc.DownloadStringCompleted += delegate { //do something };
wc.DownloadStringAsync(new Uri("http://website.com"));

または、より多くの機能を備えているが、使用するのが少し難しいHttpWebRequestを使用することもできます。

あなたがしているようにヘルパークラスを作成し、それにイベントハンドラーを追加することをお勧めします。イベントハンドラーは結果を返します。これがサンプルです。

public static event EventHandler CompletedDownload;

public static void StartGetData()
{
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://website.com");
    req.Method = "GET"; //or POST
    req.ContentType = "application/x-www-form-urlencoded";

    req.BeginGetRequestStream(GetRequestStreamCompleted, req);
}

//You can send data through this method
public static void GetRequestStreamCompleted(IAsyncResult result)
{
    HttpWebRequest req = (HttpWebRequest)result.AsyncState;
    var stream = req.EndGetRequestStream(result);

    byte[] byteData = Encoding.UTF8.GetBytes("u=" + loginData.Username + "&p=" + loginData.Password);

    stream.Write(byteData, 0, byteData.Length);
    stream.Close();

    request.BeginGetResponse(GetResponseCompleted, request);
}

public static void GetResponseCompleted(IAsyncResult result)
{
    HttpWebRequest request = (HttpWebRequest)result.AsyncState;
    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

    Stream stream = response.GetResponseStream();

    //Now trigger your CompletedDownload event, sending the deserialized data
    if (CompletedDownload != null)
        CompletedDownload(Deserializer(stream), new EventArgs());
}

次に、ダウンロードを呼び出すコードで、CompletedDownloadをサブスクライブします。オブジェクト送信側には、逆シリアル化されたデータがあります(キャストする必要があります)。次に、StartGetData()を呼び出すだけです。

編集:あなたはそれについて確信が持てないので、これがあなたのメインデータであなたが呼ぶものです...

public partial class MainPage : PhoneApplicationPage
{
    ServiceHelper.CompletedDownload += new EventHandler(ServiceHelper_CompletedDownload);

    ServiceHelper.StartGetData();
}

void ServiceHelper_CompletedDownload(object sender, EventArgs e)
{
    var q = sender as List<QueueItem>;

    //do the rest of your work here.



    //if you need to update something on the UI, you MUST call the dispatcher
    since this will be coming from a background thread... you would do this...

    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate
    {
        textBoxTitle.Text = q;
        MessageBox.Show("Download finished!");
    });
}

それは理にかなっていますか?サービスヘルパーがダウンロードを完了すると、CompletedDownloadイベントが呼び出されます。単純に順番に実行してダウンロードにすぐに何かを返すように強制できない理由は、ダウンロードが完了するまでアプリがフリーズするためです。

Windows 8とWP8では、実際には「await」と呼ばれるものを使用できます。これにより、フリーズせずに順番に処理を実行できます...ただし、WP7の場合は、これらのIAsyncResultsメソッドとコールバックメソッドを使用する必要があります。

ちなみに、イベントハンドラーを使用すると、それらを使用する方法がいくつかあります...他に2つの方法があります。

public partial class MainPage : PhoneApplicationPage
{
    ServiceHelper.CompletedDownload += delegate
    {
        string answer = "I rock";
    };

    ServiceHelper.StartGetData();
}

またはこの他のもの。これらは両方とも、現在のメソッドで定義したローカル変数に完全にアクセスできるという利点があります。この2つ目は、イベントハンドラーからオブジェクト送信者とEventArgseにもアクセスできるという利点があります。

public partial class MainPage : PhoneApplicationPage
{
    ServiceHelper.CompletedDownload += (sender, e) =>
    {
        string answer = "I rock";
    };

    ServiceHelper.StartGetData();
}

楽しみ!

于 2012-08-08T19:19:08.813 に答える
0

非同期 CTP パッケージを試すことができます。 http://msdn.microsoft.com/en-us/vstudio/async.aspx または EX を使用するのは簡単です。

Ms は C# 5 に対応していたので、非同期をサポートし、これについてはおそらく良い結果が得られるのを待っています。

http://reedcopsey.com/2010/10/28/c-5-async-part-1-simplifying-asynchrony-that-for-which-we-await/

于 2012-08-09T03:48:34.170 に答える