от
Мне нужно иметь метод, который включает в себя вызов базы данных. Этот метод должен существовать с синхронизирующим вызовом к базе данных (будет внутри SQL Server CLR), а также с асинхронным вызовом базы данных (он будет находиться в клиентском приложении). В приведенном ниже примере я хочу, чтобы MyMethodSync и MyMethodAsync совместно использовали как можно больше кода, в идеале мне нужен всего один метод с bool "call as async".
public static class MockDbAccess
{
    public static int GetDbResult(int i, string sql = null)
    {
        return i   sql?.Length ?? 0;
    }

    async public static Task GetDbResultAsync(int i, string sql = null)
    {
        await Task.Delay(2);
        return i   sql?.Length ?? 0;
    }
}

public class MyClass
{
    const string SQL = "SELECT Value FROM Table1 WHERE UniqueCode = @I";
    // COPY PASTE version:
    public int MyMethodSync(int i)
    {
        var r1 = i   4;
        var r2 = MockDbAccess.GetDbResult(r1, SQL);
        var r3 = r1   r2 * 7;
        return r3;
    }
    async public Task MyMethodAsync(int i)
    {
        var r1 = i   4;
        var r2 = await MockDbAccess.GetDbResultAsync(r1, SQL);
        var r3 = r1   r2 * 7;
        return r3;
    }

    // SHARED BUSINESS LOGIC attempt:
    int GetR1(int i) => i   4;
    int GetR3(int r1, int r2) => r1   r2 * 7;

    public int MyMethodSync_SharedCode(int i)
    {
        var r1 = GetR1(i);
        var r2 = MockDbAccess.GetDbResult(r1, SQL);
        var r3 = GetR3(r1, r2);
        return r3;
    }
    async public Task MyMethodAsync_SharedCode(int i)
    {
        var r1 = GetR1(i);
        var r2 = await MockDbAccess.GetDbResultAsync(r1, SQL);
        var r3 = GetR3(r1, r2);
        return r3;
    }

}
Попытка раздела SHARED BUSINESS LOGIC - насколько я понял. Очевидно, что в моем приложении методы getR1 и GetR3 намного сложнее. РЕДАКТИРОВАТЬ - уточнить: Мне нужна версия синхронизации для вызова метода GetDbResult () (представьте, что это какой-то вызов ADO.NET для базы данных SQL Server) и асинхронный режим для ожидания GetDbResultAsync () (это вызов основной веб-службы ASP.NET). Результат точно такой же, разница только в синхронизации и асинхронном обращении к БД.              

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.
Анти-спам проверка:
Чтобы избежать проверки в будущем, пожалуйста войдите или зарегистрируйтесь.

4 Ответы

0 голосов
от
К сожалению, нет идеального решения для этого. На данный момент есть два приличных подхода: Ваша операция, естественно, асинхронна (вызов БД), поэтому выставляйте только асинхронный API. При желании везде используйте
ConfigureAwait(false)
, чтобы синхронные потребители могли блокировать возвращаемое задание. Используйте взломанный логический аргумент. Взлом логического аргумента работает благодаря наличию основного метода с параметром
bool
со строгой семантикой: если этот параметр указывает, что результат должен быть синхронным, то основной метод должен вернуть уже выполненную задачу. Это позволяет вызывающему коду безопасно блокировать его:
public class MyClass
{
  const string SQL = "SELECT Value FROM Table1 WHERE UniqueCode = @I";
  private async Task
0 голосов
от
Если вы хотите асинхронный вызов:
await MockDbAccess.GetDbResultAsync(r1, SQL);
Если вы хотите синхронизировать вызов:
MockDbAccess.GetDbResultAsync(r1, SQL).GetAwaiter().GetResult();
Везде, где вы ждете, положите это в конце:   .ConfigureAwait (ложь); Кстати, прочитайте этот ASP.NET Core SynchronizationContext Также прочтите это: почему вы должны использовать ConfigureAwait (false)     
0 голосов
от
  В идеале я хочу только 1 метод с bool "вызвать как асинхронный". Я думаю, что это выполнимо. В приведенном ниже примере безопасно вызывать
Result
задачи, возвращаемой с помощью
async: false
, поскольку в гибридном методе не происходит ожидание, поэтому задача выполняется синхронно.
private async Task
0 голосов
от
Эти два метода будут иметь совершенно разные типы возвращаемых данных (bool vs Task
Добро пожаловать на сайт ByNets, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...