Должен ли я на самом деле использовать asyn c -wait во внутренних методах? - PullRequest
1 голос
/ 06 апреля 2020

Допустим, у меня есть 3 метода следующим образом:

public async Task<int> CalculateData(int index, int trustLevel, string type)
{
    var x = await CalculateBaseScore(index, type);
    return ComplexProcess(x, trustLevel);
}

public async Task<int> CalculateBaseScore(int index, string type)
{
    var conn_string = "...";
    var sql = "...";
    var param = new { Index = index, Type = type };
    using (var conn = new SqlConnection(conn_string))
    {
        var db_output = await conn.ExecuteScalarAsync<int>(sql, param: param);
        return db_output;
    }
}

public int CalculateBaseScore(int index, int trustLevel)
{
    //Omitted
}

Как видите, 2 из них используют asyn c -wait.

Во введении Стивена Клири asyn c -wait , сказано, что

Если вы можете написать это без ожидания, то вы должны написать это без ожидания и удалите ключевое слово asyn c из метода. Не асинхронный c метод, возвращающий Task.FromResult, более эффективен, чем асинхронный c метод, возвращающий значение.

В этом случае вызов базы данных, созданный Dapper, будет квалифицироваться как метод Я могу написать без asyn c -await и просто вернуть Task<int> объект? Получу ли я какие-либо преимущества в производительности или других аспектах, если я изменю это на это?

public async Task<int> CalculateData(int index, int trustLevel, string type)
{
    var x = await CalculateBaseScore(index, type);
    return ComplexProcess(x, trustLevel);
}

public Task<int> CalculateBaseScore(int index, string type)
{
    var conn_string = "...";
    var sql = "...";
    var param = new { Index = index, Type = type };
    using (var conn = new SqlConnection(conn_string))
    {
        var db_output_task = conn.ExecuteScalarAsync<int>(sql, param: param);
        return db_output_task;
    }
}

public int CalculateBaseScore(int index, int trustLevel)
{
    //Omitted
}

См. Во втором примере, я опустил ключевые слова asyn c -await в CalculateBaseScore и просто возвратил Task объект.

1 Ответ

3 голосов
/ 06 апреля 2020

Что касается второй реализации без asyn c -await:

public Task<int> CalculateBaseScore(int index, string type)
{
    var conn_string = "...";
    var sql = "...";
    var param = new { Index = index, Type = type };
    using (var conn = new SqlConnection(conn_string))
    {
        var db_output_task = conn.ExecuteScalarAsync<int>(sql, param: param);
        return db_output_task;
    }
}

... даст вам повышение производительности примерно на 1 мкс c за вызов. Другими словами, это сэкономит вам целую секунду процессорного времени после его запуска 1 000 000 раз. Это хорошая новость.

Плохая новость заключается в том, что все эти 1 000 000 вызовов приведут к ObjectDisposedException, потому что SqlConnection будет удалено преждевременно, сразу после создания Task.

Стоит ли это того? Я бы сказал нет. Сохранение этого простым сэкономит вам больше времени в долгосрочной перспективе.

...