【问题标题】:Asynchronous programming model and application scale异步编程模型和应用规模
【发布时间】:2014-02-24 15:21:55
【问题描述】:

我希望更好地了解异步编程模型。假设下面调用的 Web 服务需要 1 秒才能返回:

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();

    string urlContents = await client.GetStringAsync("http://service.com");

    return urlContents.Length;
}

await与异步方法一起使用时,当前线程被让出回线程池做其他工作是否正确?使用异步模型是否会为每个请求节省 1 秒的工作时间,因为该线程不会等待 Web 服务响应?

【问题讨论】:

  • 定义saving 1 second of work。每个请求是否正好是一秒?多线程永远不会节省您的工作量。总是要执行相同的工作。但是,它可以节省您的时间。
  • 一般来说,这意味着线程可以用于其他工作。异步 GetStringAsync 方法使用异步 I/O 回调,因此它甚至不需要使用新线程。换句话说,在 I/O 绑定的应用程序中,拥有更多线程根本没有帮助。异步调用AccessTheWebAsync 100 次意味着将花费或多或少一秒,而不是如果在一个线程中同步完成则需要 100 秒。
  • @Gusdor 通过节省,我的意思是线程不会花费一些时间不做有用的工作,因为它正在等待响应。

标签: c# asynchronous


【解决方案1】:

说await配合异步方法使用时,将当前线程yield回线程池做其他工作对吗?

是的。

使用异步模型是否会为每个请求节省 1 秒的工作时间,因为该线程不会等待 Web 服务响应?

它为那一秒释放了一个本来会阻塞的线程。

从单个请求的角度来看,这没有区别;请求仍然要等待操作完成,请求不关心是同步等待(阻塞)还是异步等待(等待)。但从整个服务器应用程序的角度来看,这会有所不同:处理大量请求所需的线程更少。

【讨论】:

    【解决方案2】:

    当调用await 语句时,调用线程立即返回。如果您在上下文线程(UI 或 ASP.net 线程)上,则行为不同,但结果基本相同。

    只有在没有其他代码跟随并且vcalling线程实际上是线程池线程时,该线程才会返回池。

    【讨论】:

      【解决方案3】:

      我尝试在 WebApi 中使用 asyncawait 调用。发生的情况是,当您到达await 语句时,控制权将交给调用方法,直到任务(在本例中为client.GetStringAsync("http://service.com"))完成。这是一个问题,因为调用方法尝试返回一个值,而不管任务是否完成,如果任务完成你会得到一个异常,像

      在异步任务仍在进行时调用了 return 语句

      在您的情况下,由于您只有 1 个操作,即从另一个站点获取内容,因此您不需要它是异步的。如果您从 2 个或更多不同的站点获取内容,那么使用异步调用是有意义的。

      【讨论】:

        猜你喜欢
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-17
        • 1970-01-01
        • 2010-12-18
        • 1970-01-01
        相关资源
        最近更新 更多