C#性能影响异步函数调用异步函数

时间:2018-05-25 13:54:15

标签: c# .net asp.net-mvc

我正在编写代码,最后我从另一个异步方法调用异步方法。我想知道这种做法对性能的影响。是否导致为每个async-await使用如此多的线程?

一个例子可以帮助

public async Task<IHttpActionResult> ControllerMethod() 
{
    :
    return await A1();
}

public async Task<R1> A1() 
{
    :
    var result = await A2();
    if (result != null) 
    {  
        A3() 
    }
    return result;
}

public async Task<R1> A2() 
{
    :
    var result = await A4();
    return result;
}

public void A3() 
{
    :
    // call to another async method without await
}

请帮助我理解 - 这是不好的做法?这是重构代码的结果

2 个答案:

答案 0 :(得分:1)

成本和性能影响表明,标记为异步的每个方法都会在幕后转移到状态机中;所以必须要处理更多代码和状态机实例。

您可以避免使用重写的状态机,如下所示;如果该语句后面没有代码,则不必等待,只需按照下面的A2方法返回任务即可。

// PackageControllerTest.php

namespace Tests\Feature;

use Tests\TestCase;
use App\Contracts\PackageInterface;
use App\Http\Controllers\PackageController;
use Illuminate\Database\Eloquent\Collection;

class PackageControllerTest extends TestCase
{
    protected $mock;
    protected $target;

    public function setUp()
    {
        parent::setUp();

        parent::initDatabase();

        $this->mock = $this->initMock(PackageInterface::class);
        $this->target = $this->app->make(PackageController::class);
    }

    public function testIndex()
    {
        $expected = new Collection([
            ['name' => 'Name 1', 'html_url' => 'HTML URL 1'],
            ['name' => 'Name 2', 'html_url' => 'HTML URL 2'],
            ['name' => 'Name 3', 'html_url' => 'HTML URL 3'],
        ]);

        $this->mock
            ->shouldReceive('getAllPackages')
            ->once()
            ->andReturn($expected);

        $actual = $this->target->index()->packages;

        $this->assertEquals($expected, $actual);
    }

    public function testUpdate()
    {
        //
    }

    public function tearDown()
    {
        parent::resetDatabase();

        $this->mock = null;
        $this->target = null;
    }
}

答案 1 :(得分:0)

这完全不是一个坏习惯。如果您正在分解的小方法做了一些真正需要异步操作的工作,则情况正好相反。假设在方法 A4()中,您正在从文件中读取数据(非CPU绑定操作,不需要来自ASP .NET线程池的任何线程)。如果您在此操作中不使用异步,则在从文件中读取数据时,您的线程将无法执行任何操作。

相反,如果你使用异步,线程将返回到线程池,并且线程池将能够用新释放的线程提供更多请求。