【问题标题】:C# Asynchronous HTTPWebRequest on Windows PhoneWindows Phone 上的 C# 异步 HTTPWebRequest
【发布时间】:2013-05-23 21:47:15
【问题描述】:

我是 .Net 和 Windows Phone 开发的新手。我目前正在研究通过 HTTPWebrequest 类发出异步 Web 请求的不同方法。

异步和等待:

async 和 await 似乎是一种发出异步 Web 请求的好方法:http://blog.stephencleary.com/2012/02/async-and-await.html。我唯一担心的是,根据文档,在执行任务时调用方法线程会被挂起。我想让调用方法立即返回,怎么办?

public async Task NewStuffAsync()
{
  // Use await and have fun with the new stuff.
  await ...
}

public Task MyOldTaskParallelLibraryCode()
{
  // Note that this is not an async method, so we can't use await in here.
  ...
}

public async Task ComposeAsync()
{
  // We can await Tasks, regardless of where they come from.
  await NewStuffAsync();
  await MyOldTaskParallelLibraryCode();
}

HttpWebRequest.BeginGetResponse

这是来自 Microsoft 的示例:http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

我想了解与回调相关的开销。

线程池

托管线程池似乎很健壮。我再次想了解与之相关的开销。

http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

【问题讨论】:

  • 如果您在使用HttpWebRequest 的情况下编译您的代码,您将收到该类已过时的警告。按照建议使用HttpClient

标签: c# asynchronous windows-phone-8 httpclient


【解决方案1】:

我实际上一直在尝试这个。我发布了代码,以便您可以使用它。使用async/await和使用回调其实是有区别的。 async/await 对我来说更自然。

考虑以下代码。顺便说一句,这是一个控制台应用程序。两种代码实现了相同的目的。

    static void Main(string[] args)
    {
        MakeRequest();       

        Console.ReadLine();
    }

    private static async void MakeRequest()
    {
        await UseHttpClient();
        UseWebClient();
    }

    private static async Task UseHttpClient()
    {
        Console.WriteLine("=== HttpClient ==");
        var client = new HttpClient();
        var request = new HttpRequestMessage(HttpMethod.Get, new Uri("http://www.google.com"));
        Console.WriteLine("HttpClient requesting...");
        var response = await client.SendAsync(request);
        Console.WriteLine(response.Content.ReadAsStringAsync().Result.Substring(0,100));
        Console.WriteLine("HttpClient done");
    }

    private static void UseWebClient()
    {
        Console.WriteLine("=== WebClient ==");
        var webClient = new WebClient();
        webClient.DownloadStringAsync(new Uri("http://www.google.com"));
        Console.WriteLine("WebClient requesting...");
        webClient.DownloadStringCompleted += (sender, eventArgs) => Console.WriteLine(eventArgs.Result.Substring(0,100));
        Console.WriteLine("WebClient done.");
    }

这些是输出:

对于HttpClient

=== HttpClient ==
HttpClient requesting...
<!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage">
<head><meta itemprop
HttpClient done

对于使用回调的WebClient

=== WebClient ==
WebClient requesting...
WebClient done.
<!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage">
<head><meta itemprop

如您所见,HttpClient 实际上在继续流程之前首先等待结果(它实际上返回给调用者)。因此,关键字await,它等待并稍后执行。

但是使用回调时流程完全不同。您的代码连续流动(这就是为什么您可以看到在实际结果之前打印WebClient done。为了实现与 async/await 相同的流程,有多种方法。其中之一是利用 TCS 并包装您的围绕它的函数(我不会在这里介绍,因为这已经介绍过很多次了)。最简单的方法是使用HttpClient

希望它有助于理解async/await 和使用回调。

【讨论】:

    【解决方案2】:

    我建议安装Microsoft.Net.Http NuGet 包并使用 HttpClient。这内置了异步等待支持。

    【讨论】:

      【解决方案3】:

      我唯一担心的是,根据文档,在执行任务时调用方法线程会被挂起。

      没有;使用async/await,你可以这样想:方法被挂起,但线程返回并继续运行。所以 UI 仍然是响应式的。

      按照 Blounty 的建议,查看 Microsoft.Net.Http 包中的 HttpClient(目前在 RC 中)。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,我发现了这个并帮助了我

        private async Task<T> ExecuteAsync<T>(RestRequest request)
        {
            var tcs = new TaskCompletionSource<T>();
            _client.ExecuteAsync(request, resp =>
            {
                var value = JsonConvert.DeserializeObject<T>(resp.Content);
                if (value.ErrorCode > 0)
                {
                    var ex = new ToodledoException(value.ErrorCode, value.ErrorDesc);
                    tcs.SetException(ex);
                }
                else
                    tcs.SetResult(value);
            });
            return await tcs.Task;
        }
        

        http://www.developer.nokia.com/Community/Wiki/Asynchronous_Programming_For_Windows_Phone_8 我也发现这个扩展很有帮助http://nuget.org/packages/WP8AsyncWebClient/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多