异步等待性能 - 直接方法调用与任务包装器调用

  发布于 2022-12-18 13:57

我创建的一个小程序,用于理解Async Await的工作并在for循环中调用async方法,作为直接方法调用:

sumProgram.CallSum(i, i + 1);

或使用Task API Task.Run / Task.Factory.StartNew

我最初的理解是Task API会使它大大加快,但与我的期望相反,这肯定反映了我的理解不足,直接调用在性能方面要好得多.实际上,当在GetSum方法中引入额外的线程休眠时,它似乎只会影响任务调用,而且也会影响很大.

现在我理解直接调用的第一部分更快,因为它们是异步执行的,并且没有添加到任务列表并使它们等待的开销,但是当我将相同的技术转移到真正的编程范例时,那么问题遗迹:

对于直接调用,没有什么可以模拟Task.WaitAll,所以他们会退出调用方法,即使所有执行都没有完成,所以我唯一的选择任务包装器.

我得到了令人费解的结果,因为对于直接调用,秒表将在所有执行完成之前发布时间,并且由于waitAll,任务包装器不会出现这种情况.

要执行此程序,您需要注释/取消注释相关部分以获得正确的结果

 class Program
    {
        static void Main(string[] args)
        {
            Program sumProgram = new Program();

        List taskList = new List(); // Only For Task

        Stopwatch sw = Stopwatch.StartNew();

        for (int i = 0; i < 100000; i++)
        {
            taskList.Add(Task.Factory.StartNew(() => { sumProgram.CallSum(i, i + 1); })); // For Task use one 
            taskList.Add(Task.Run(() => { sumProgram.CallSum(i, i + 1); })); // For Task use one 
            sumProgram.CallSum(i, i + 1);
        }

        Task.WaitAll(taskList.ToArray()); // Only For Task

        sw.Stop();
        Console.WriteLine("Time Elapsed :: " + sw.ElapsedMilliseconds);
    }

    public async Task CallSum(int num1, int num2)
    {
        Func callFunc = (() =>
        {
            return GetSum(num1, num2);
        });

        int result = await Task.Run(callFunc);
        //Console.WriteLine("Sum Result :: " + result);
    }

    public int GetSum(int num1, int num2)
    {
        Thread.Sleep(10);
        return (num1 + num2);
    }
}

Stephen Clea.. 5

async !="更快"

事实上,async代码几乎总是(略微)慢.

那么,为什么要使用async

在客户端(UI)应用程序上,async允许您保持对用户的响应.对比此代码:

void Button_Click()
{
  Thread.Sleep(10000);
}

使用此代码:

async void Button_Click()
{
  await Task.Delay(10000);
}

在服务器端(例如,ASP.NET),async允许您的代码使用更少的线程来提供更多请求.因此,提高了可扩展性.

请注意,在这两种情况下,async代码实际上都比同步代码.对于UI,睡眠当前线程比创建和启动计时器,创建和等待任务,然后在计时器触发时恢复异步方法更快.对于ASP.NET,阻塞当前线程比为异步操作创建任务更快,然后在异步方法恢复时将请求上下文切换到另一个线程.

但是,async带来其他好处.对于UI,在延迟期间不会阻止UI线程.对于ASP.NET,请求线程可以在异步操作正在进行时自由处理其他请求.

async不是速度; 它是关于释放当前线程.

1 个回答
  • async !="更快"

    事实上,async代码几乎总是(略微)慢.

    那么,为什么要使用async

    在客户端(UI)应用程序上,async允许您保持对用户的响应.对比此代码:

    void Button_Click()
    {
      Thread.Sleep(10000);
    }
    

    使用此代码:

    async void Button_Click()
    {
      await Task.Delay(10000);
    }
    

    在服务器端(例如,ASP.NET),async允许您的代码使用更少的线程来提供更多请求.因此,提高了可扩展性.

    请注意,在这两种情况下,async代码实际上都比同步代码.对于UI,睡眠当前线程比创建和启动计时器,创建和等待任务,然后在计时器触发时恢复异步方法更快.对于ASP.NET,阻塞当前线程比为异步操作创建任务更快,然后在异步方法恢复时将请求上下文切换到另一个线程.

    但是,async带来其他好处.对于UI,在延迟期间不会阻止UI线程.对于ASP.NET,请求线程可以在异步操作正在进行时自由处理其他请求.

    async不是速度; 它是关于释放当前线程.

    2022-12-18 14:01 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有