0

我将首先了解异步性和非 UI 冻结应用程序的重要性。我真正喜欢的整个 async/await 世​​界,甚至是 APM,或者使用Task.

没关系,但是我有一个场景,我真的需要等待 Web 服务 POST 完成然后继续。

public void DoSomeWorkNow()
{
   // Do stuff...
   // Do more stuff...
   // Make the web service call..
   // The request should finish and I should continue doing stuff....
   // Do stuff...
}

我不能使用 async/await,即使我想要,它也不能解决问题。我可以使用,但您可以参考我在这里Task.FromAsync遇到的问题我 不能使用第 3 方库,因为这是一个库并且不想要第 3 方依赖项。

这应该是同步的确实是有原因的,不会详细说明,这不是设计问题,而是设计功能。

使用 WebRequest Begin/End 操作,请求/响应通过回调发生。这很棒,而且效果很好。现在没有 API 可以同步调用 Web 服务,Windows Phone 8 SDK 不支持 GetRequest/GetRespone。

我尝试使用互斥锁并调用一个Wait在 Web 服务类调用内部的方法,Mutex.WaitOne()假设它将暂停调用方法,直到完成请求并获得响应的最后一个回调将发出释放信号。

理论上它应该可以工作,但是在调用 时WaitOne(),最后一个回调永远不会返回来完成这项工作。

然后我想使用IAsyncResultBeginXyz/EndXyz 方法的返回值IsComplete在 while 循环中检查,如果为真则中断继续。没有成功。

那么,我想知道,是否有一种可行的高效解决方案来同步调用 Web 服务?

搜索谷歌和stackoverflow,没有返回任何工作解决方案。

更新

这是我尝试的一些代码:

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

                    DataWebRequest webRequestState = new DataWebRequest
                    {
                        Data = requestData,
                        FileName = filePath,
                        Request = request
                    };

                    IAsyncResult requestResult = request.BeginGetRequestStream(ar =>
                    {
                        DataWebRequest webRequestData = (DataWebRequest )ar.AsyncState;
                        HttpWebRequest requestStream = (HttpWebRequest)webRequestData.Request;

                        string data = webRequestData.Data;

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

                        try
                        {
                            // End the operation
// Here the EndGetRequestStream(ar) throws exception System.InvalidOperationException: 
// Operation is not valid due to the current state of the object
                            using (Stream endGetRequestStream = requestStream.EndGetRequestStream(ar))
                            {
                                // Write to the request stream.
                                endGetRequestStream.Write(postBytes, 0, postBytes.Length);
                            }

                            requestStream.BeginGetResponse(GetResponseCallback, webRequestData);
                        }
                        catch (WebException webEx)
                        {
                            WebExceptionStatus status = webEx.Status;
                            WebResponse responseEx = webEx.Response;
                            Debug.WriteLine(webEx.ToString());
                        }
                    }, webRequestState);

    // The below while loop is actually breaking as the IsCompleted is true, but an
    // exception System.InvalidOperationException is thrown after a while
                    while (true)
                    {
                        if (requestResult.IsCompleted) break;
                    }

                    IAsyncResult responseResult = request.BeginGetResponse(ar =>
                    {
                        DataWebRequest webRequestData = (DataWebRequest)ar.AsyncState;
                        HttpWebRequest httpWebRequest = (HttpWebRequest)webRequestData.Request;

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

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

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

                                Debug.WriteLine("Response : {0}", responseString);

                                // Maybe do some other stuff....
                            }
                        }
                        catch (WebException webEx)
                        {
                            WebExceptionStatus status = webEx.Status;
                            WebResponse responseEx = webEx.Response;
                            Debug.WriteLine(webEx.ToString());
                        }

                    }, webRequestState);

    // This while loop never actually ends!!!
                    while (true)
                    {
                        if (responseResult.IsCompleted) break;
                    }
            }

谢谢你。

4

0 回答 0