ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

任务创建开销

2019-12-11 06:06:46  阅读:227  来源: 互联网

标签:asynchronous lazy-evaluation task c


我正在读一本书《 Terrell R.-.NET中的并发性》.

有一个不错的代码示例:

Lazy<Task<Person>> person = new Lazy<Task<Person>>(
     async () =>
     {
         using (var cmd = new SqlCommand(cmdText, conn))
         using (var reader = await cmd.ExecuteReaderAsync())
         {
             // some code...
         }
     });

async Task<Person> FetchPerson()
{
    return await person.Value;
}

作者说:

Because the lambda expression is asynchronous, it can be executed on
any thread that calls Value, and the expression will run within the
context.

据我了解,线程来到FetchPerson并停留在Lamda执行中.真的不好吗?有什么后果?

作为解决方案,作者建议创建一个任务:

Lazy<Task<Person>> person = new Lazy<Task<Person>>(
      () => Task.Run(
        async () =>
        {
            using (var cmd = new SqlCommand(cmdText, conn))
            using (var reader = await cmd.ExecuteReaderAsync())
            {
                // some code...
            }
        }));

真的对吗?这是一个IO操作,但是我们从Threadpool窃取了CPU线程.

解决方法:

Because the lambda expression is asynchronous, it can be executed on any thread that calls Value, and the expression will run within the context.

lambda可以从任何线程运行(除非您对允许访问Lazy的值的线程类型非常小心),因此它将在该线程的上下文中运行.这不是因为它是异步的,即使它是同步的,也可以在任何调用它的线程的上下文中运行,这都是正确的.

As i understand it, the Thread come to FetchPerson and is stuck in Lamda execution.

lambda是异步的,因此它将(如果正确实现)几乎立即返回.这就是异步的含义,因为它不会阻塞调用线程.

Is that realy bad? What consequences?

如果您错误地实现了异步方法,并使其长时间运行同步工作,那么是的,您正在阻塞该线程/上下文.如果您不这样做,那么您就不是.

另外,默认情况下,异步方法中的所有继续都将在原始上下文中运行(如果它完全具有SynchonrizationContext).在您的情况下,您的代码几乎可以肯定不依赖于重用该上下文(因为您不知道调用者可能拥有的上下文,所以我无法想象您编写了其余代码来使用它).鉴于此,您可以在等待的任何对象上调用.ConfigureAwait(false),这样就不会将当前上下文用于这些继续.为了避免浪费时间在原始上下文上安排工作,等待其他需要它的时间,或者在不必要的时候让其他任何东西等待此代码,这只是性能的微小改进.

As a solution, the author suggest to create a Task: […] Is that really correct?

它不会破坏任何东西.它将安排工作在线程池线程中运行,而不是在原始上下文中运行.首先,这会产生一些额外的开销.您只需将ConfigureAwait(false)添加到您要等待的所有内容中,就可以用较低的开销完成大约相同的事情.

This is an IO operation, but we steal CPU thread from Threadpool.

该代码段将在线程池线程上启动IO操作.由于该方法仍然是异步的,因此它将在启动后立即将其返回到池中,并在每次等待后从池中获取一个新线程以再次开始运行.后者可能适合这种情况,但是将代码启动以启动初始异步操作到线程池线程只是增加了无实际值的开销(因为操作如此短,您将花费更多的精力在线程上进行调度池线程而不是仅运行它).

标签:asynchronous,lazy-evaluation,task,c
来源: https://codeday.me/bug/20191211/2106989.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有