[英]How do I actually get the response of an async web request from outside the method?
我有點困惑。 我正在嘗試以異步方式發布到我的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, 0, 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是正確的,您應該使用using
來讓您的流正確關閉(並保證):
在您的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)線程上,這將導致線程上下文異常)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.