将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

将asynccallback方法转换为Task<Result>方法

首先,我强烈建议您升级到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();
    }
}