c# – 如何从方法外部获得异步Web请求的响应?
发布时间:2020-12-15 17:24:53 所属栏目:百科 来源:网络整理
导读:我有点困惑.我试图以异步方式发布到我的Web服务,理想情况下我想启动请求,在UI上显示加载微调器,然后当异步请求完成处理响应时,如果有响应则显示错误,或者用结果做另一个操作. 这是我的代码,我在这里调用请求并传递一些数据. private void SignInExecute(){ i
我有点困惑.我试图以异步方式发布到我的Web服务,理想情况下我想启动请求,在UI上显示加载微调器,然后当异步请求完成处理响应时,如果有响应则显示错误,或者用结果做另一个操作.
这是我的代码,我在这里调用请求并传递一些数据. private void SignInExecute() { if (Username == null || Password == null) { LoginOutput = "Please provide a username or password."; } else { this.webService.SendLoginRequest("http://localhost:3000/client_sessions","username=" + Username + "&password=" + Password); } } 这是实际的Web请求代码: public void SendLoginRequest(string url,string postdata) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Accept = "application/json"; byte[] byteArray = Encoding.UTF8.GetBytes(postdata); request.CookieContainer = new CookieContainer(); request.ContentLength = byteArray.Length; Stream dataStream = request.GetRequestStream(); dataStream.Write(byteArray,byteArray.Length); dataStream.Close(); ((HttpWebRequest)request).KeepAlive = false; request.BeginGetResponse(new AsyncCallback(GetLoginResponseCallback),request); } private static void GetLoginResponseCallback(IAsyncResult asynchronousResult) { HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; // End the operation HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); Stream streamResponse = response.GetResponseStream(); StreamReader streamRead = new StreamReader(streamResponse); string responseString = streamRead.ReadToEnd(); Console.WriteLine(responseString); // Close the stream object streamResponse.Close(); streamRead.Close(); response.Close(); } 所以总结一下.我希望能够将响应返回给最初调用Web请求启动的对象.有帮助吗? 解决方法
您需要告诉BeginGetResponse返回到通过SynchronizationContext.Current调用它的相同上下文.像这样的东西(代码没有正确的错误检查,所以你应该正确考虑)(另外,Platinum Azure是正确的,你应该使用一个使你的流正常关闭(并保证):
在您的SendLoginRequest中: //Box your object state with the current thread context object[] boxedItems = new []{request,SynchronizationContext.Current}; request.BeginGetResponse(new AsyncCallback(GetLoginResponseCallback),boxedItems); getresponse代码: private static void GetLoginResponseCallback(IAsyncResult asynchronousResult) { //MY UPDATE //Unbox your object state with the current thread context object[] boxedItems = asynchronousResult.AsyncState as object[]; HttpWebRequest request = boxedItems[0] as HttpWebRequest; SynchronizationContext context = boxedItems[1] as SynchronizationContext; // End the operation using(HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult)) { using(Stream streamResponse = response.GetResponseStream()) { using(StreamReader streamRead = new StreamReader(streamResponse)) { string responseString = streamRead.ReadToEnd(); Console.WriteLine(responseString); //MY UPDATE //Make an asynchronous call back onto the main UI thread //(context.Send for a synchronous call) //Pass responseString as your method parameter //If you have more than one object,you will have to box again context.Post(UIMethodToCall,responseString); } } } } 实现UI处理 public static void UIMethodCall(object ObjectState) { String response = ObjectState as String; label1.Text = String.Format("Output: {0}",response); //Or whatever you need to do in the UI... } 现在,我会先测试一下这个.我对Microsoft实现事件驱动异步的理解是,响应是上下文感知的,并且知道返回哪个上下文.因此,在跳到假设您不在同一个上下文之前,通过尝试更新UI来测试它(如果您不在调用(UI)线程上,这将导致线程上下文异常) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |