将asynccallback方法转换为Task方法
本文关键字:方法 Result Task asynccallback 转换 | 更新日期: 2023-09-27 18:08:17
想改变我的方法从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);
}
下一步我使用了下面的链接:将回调函数转换为任务模式现在我想要一个这样的包装器方法:
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);
}
问题:这不起作用,因为回调是异步的,因此线程在回调被触发之前停止。这只是我的猜测。我该怎么做呢?
Thanks in advance
首先,我强烈建议您升级到HttpClient
。
但是如果你想用更难的方法,那么你可以这样做:
public static Task<string> DownloadStringAsync()
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
DownloadString(result => tcs.SetResult(result));
return tcs.Task;
}
你可以从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();
}
}