希望将我的方法从HttpWebRequest.BeginGetRequestStream和HttpWebRequest.BeginGetResponse更改为使用async和Tasks的方法。我需要使用这些方法,因为我在Windows Phone上工作,并且此平台上没有其他非异步的GetRequestStream方法。
这是我的方法DownloadString:
private static Action<string> completed;
public static void DownloadString(Action<string> c)
{
completed = c;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("linkhere", UriKind.Absolute));
request.Method = "POST";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5Accept: */*";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request.BeginGetRequestStream(RequestCallback, request);
}
private static void RequestCallback(IAsyncResult ar)
{
HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
Stream postStream = request.EndGetRequestStream(ar);
//some post data
request.BeginGetResponse(ResponseCallback, request);
}
private static void ResponseCallback(IAsyncResult ar)
{
HttpWebRequest webRequest = (HttpWebRequest)ar.AsyncState;
HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(ar);
Stream streamResponse = response.GetResponseStream();
StreamReader streamReaders = new StreamReader(streamResponse);
string content = streamReaders.ReadToEnd();
streamResponse.Close();
streamReaders.Close();
response.Close();
completed.Invoke(content);
}
对于下一步,我使用了以下链接: Converting Callback Functions to Task Pattern 现在我想要一个这样的包装器方法:
public async static Task<string> DownloadWithoutAction()
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
var task = tcs.Task;
Action<string> callback = tcs.SetResult;
await Task.Factory.StartNew(() =>
{
DownloadString(callback);
}, TaskCreationOptions.AttachedToParent);
return await Task.FromResult(task.Result);
}
问题: 这不起作用,因为回调是异步的,因此线程在回调被触发之前停止。这只是我的猜测。我该如何解决?
提前致谢
答案 0 :(得分:3)
首先,我强烈建议您升级到HttpClient
。
但如果你想以更难的方式去做,那么你会做这样的事情:
public static Task<string> DownloadStringAsync()
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
DownloadString(result => tcs.SetResult(result));
return tcs.Task;
}
答案 1 :(得分:0)
您可以使用TaskFactory中的FromAsync方法:
var request = HttpWebRequest.CreateHttp("http://url");
var stream = await Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, TaskCreationOptions.None);
var response = (HttpWebResponse)(await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, TaskCreationOptions.None));
使用Tasks的方法可以是:
private async Task<string> DownloadString()
{
var request = (HttpWebRequest)WebRequest.Create(new Uri("linkhere", UriKind.Absolute));
request.Method = "POST";
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.52 Safari/536.5Accept: */*";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
using (var response = (HttpWebResponse)(await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, TaskCreationOptions.None)))
using (var streamResponse = new StreamReader(response.GetResponseStream()))
{
return await streamResponse.ReadToEndAsync();
}
}