2

この単純なコードで私が間違ったことを誰か教えてもらえますか? 実行するとハングアップします

using (Stream postStream = request.EndGetRequestStream(asynchronousResult))

requestState.Wait.WaitOne(); をコメントアウトすると、コードは正しく実行されますが、明らかに応答を待ちません。EndGetRequestStream への呼び出しが何らかの形でメインスレッドのコンテキストに戻っていると思いますか?? ただし、私のコードは基本的にサンプルと同じであると確信しています ( MSDN ドキュメント) 。

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Text;

namespace SBRemoteClient
{
    public class JSONClient
    {

        public string ExecuteJSONQuery(string url, string query)
        {
            System.Uri uri = new Uri(url);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "POST";
            request.Accept = "application/json";
            byte[] requestBytes = Encoding.UTF8.GetBytes(query);
            RequestState requestState = new RequestState(request, requestBytes);
            IAsyncResult resultRequest = request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), requestState);
            requestState.Wait.WaitOne();
            IAsyncResult resultResponse = (IAsyncResult)request.BeginGetResponse(new AsyncCallback(GetResponseStreamCallback), requestState);
            requestState.Wait.WaitOne();

            return requestState.Response;
        }

        private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                RequestState requestState = (RequestState)asynchronousResult.AsyncState;
                HttpWebRequest request = requestState.Request;
                using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
                {
                    postStream.Write(requestState.RequestBytes, 0, requestState.RequestBytes.Length);
                }
                requestState.Wait.Set();
            }
            catch (Exception e) {
                Console.Out.WriteLine(e);
            }
        }

        private static void GetResponseStreamCallback(IAsyncResult asynchronousResult)
        {
            RequestState requestState = (RequestState)asynchronousResult.AsyncState;
            HttpWebRequest request = requestState.Request;
            using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (StreamReader streamRead = new StreamReader(responseStream))
                    {
                        requestState.Response = streamRead.ReadToEnd();
                        requestState.Wait.Set();
                    }
                }
            }
        }
    }
}
4

1 に答える 1

1

いくつかのこと:

  1. 同じリクエストオブジェクトを再利用できるとは思いません。つまり、HttpWebRequest のインスタンスごとに 1 回、BeginGetRequestStream を呼び出すことができます。2 つの要求 (サーバーへの呼び出し) を実行する場合は、要求ごとに 1 つずつ、HttpWebRequest の 2 つのインスタンスが必要です。

  2. 同期動作が必要な場合は、2 つのオプションがあります。GetRespose メソッドを使用するか、begin/end を同期的に使用します。そのために、コールバックを BeginGetRequestStream メソッドに渡す必要はありません (代わりに null を渡すことができます)。BeginGetRequestStream (IAsyncResult) から返された値を取得し、それを EndGetRequestStream メソッドに渡します。

    AsyncResult resultRequest = request.BeginGetRequestStream(null, null);
    Stream postStream = request.EndGetRequestStream(asynchronousResult)
    

EndGetRequestStream は、リクエストが完了するまでブロックします (UI から実行している場合、これは良くありませんが、それでも機能します)。

于 2010-03-28T19:59:43.073 に答える