0

WebRequest を実装し、呼び出し元に同期的に返そうとしています。私はさまざまな実装を試しましたが、これが今のところ最も適切だと思います。

InvalidOperationException残念ながら、次のコードはメッセージとともに をスローします

EndGetResponse は、非同期操作ごとに 1 回だけ呼び出すことができます

私はこれを実現するのに十分苦労しましたが、このように WebRequest を使用するために構築するライブラリにとって非常に重要です。

次のコードは、Windows Phone 8 および Windows 8 プラットフォームでの使用を意図しています。

私はすでに async/await パターンを理解して使用していますが、ライブラリの一部で同期バージョンの Web サービス リクエストを使用することは非常に重要です。

コード:

public void ExecuteRequest(string url, string requestData)
{
        WebRequest request = WebRequest.Create(new Uri(url));
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.Headers["Header-Key"] = "AKey";

        DTOWebRequest webRequestState = new DTOWebRequest
        {
            Data = requestData,
            Request = request
        };

        ManualResetEventSlim resetEventSlim = new ManualResetEventSlim(false);

        // Begin the request using a delegate
        request.BeginGetRequestStream(ar =>
        {
            DTOWebRequest requestDataObj = (DTOWebRequest )ar.AsyncState;
            HttpWebRequest requestStream = (HttpWebRequest)requestDataObj.Request;

            string data = requestDataObj.Data;

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

            try
            {
                // End the operation
                using (Stream endGetRequestStream = requestStream.EndGetRequestStream(ar))
                {
                    // Write to the request stream.
                    endGetRequestStream.Write(postBytes, 0, postBytes.Length);
                }

                // Get the response using a delegate
                requestStream.BeginGetResponse(result =>
                {
                    DTOWebRequest requestDataObjResult = (DTOWebRequest )ar.AsyncState;
                    HttpWebRequest requestResult = (HttpWebRequest)requestDataObjResult.Request;

                    try
                    {
                        // End the operation
                        using (HttpWebResponse response = (HttpWebResponse)requestResult.EndGetResponse(ar)) // Here the exception is thrown.
                        {
                            HttpStatusCode rcode = response.StatusCode;
                            Stream streamResponse = response.GetResponseStream();
                            StreamReader streamRead = new StreamReader(streamResponse);

                            // The Response
                            string responseString = streamRead.ReadToEnd();

                            if (!string.IsNullOrWhiteSpace(requestDataObjResult.FileName))
                            {
                                FileRepository fileRepo = new FileRepository();
                                fileRepo.Delete(requestDataObjResult.FileName);
                            }

                            Debug.WriteLine("Response : {0}", responseString);
                        }
                    }
                    catch (WebException webEx)
                    {
                        WebExceptionStatus status = webEx.Status;
                        WebResponse responseEx = webEx.Response;
                        Debug.WriteLine(webEx.ToString());
                    }

                    resetEventSlim.Set(); // Signal to return handler
                }, requestDataObj);
            }
            catch (WebException webEx)
            {
                WebExceptionStatus status = webEx.Status;
                WebResponse responseEx = webEx.Response;
                Debug.WriteLine(webEx.ToString());
            }    
        }, webRequestState);

        resetEventSlim.Wait(5000); // Wait either for Set() or a timeout 5 secs.
    }
}

ありがとうございました。

4

1 に答える 1

1

Windows Phone で同期 Web 通話を行うことはできません。それが理由です。

もしそうなら、 /GetRequestStreamの代わりに呼び出しているでしょう。BeginGetRequestStramEndGetRequestStream

Windows Phone で同期する唯一の理由は、非常に悪い考えである UI をブロックすることです。

HttpClient代わりに and àsync-await` を使用する必要があります。

しかし、Windows Phone で非同期呼び出しを行う必要がある (そしてできる) と本当に思っている場合は、いつでも次のようなことを試すことができます。

public void ExecuteRequest(string url, string requestData)
{
    try
    {
        WebRequest request = WebRequest.Create(new Uri(url));
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.Headers["Header-Key"] = "AKey";

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

        using (var requestStream = request.EndGetRequestStream(request.BeginGetRequestStream(null, null)))
        {
            // Write to the request stream.
            endGetRequestStream.Write(postBytes, 0, postBytes.Length);
        }

        using (var response = request.EndGetResponse(request.BeginGetResponse(null, null)))
        {
            using (var streamRead = new StreamReader(response.GetResponseStream()))
            {
                // The Response
                string responseString = streamRead.ReadToEnd();

                if (!string.IsNullOrWhiteSpace(requestDataObjResult.FileName))
                {
                    var fileRepo = new FileRepository();
                    fileRepo.Delete(request.FileName);
                }

                Debug.WriteLine("Response : {0}", responseString);
            }
        }
    }
    catch (WebException webEx)
    {
        WebExceptionStatus status = webEx.Status;
        WebResponse responseEx = webEx.Response;
        Debug.WriteLine(webEx.ToString());
    }    
}

しかし、あなたの決定/必要性を修正する必要があると本当に思います.

于 2013-09-08T22:33:16.940 に答える