C # async ожидает HTTP-сервер, который иногда не работает [дублировать]

ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.

function* myGenerator() {
    const callback = yield;
    let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
    console.log("response is:", response);

    // examples of other things you can do
    yield setTimeout(callback, 1000);
    console.log("it delayed for 1000ms");
    while (response.statusText === "error") {
        [response] = yield* anotherGenerator();
    }
}

Для запуска вышеуказанного кода вы делаете это:

const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function

Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.

Обратный вызов ...args завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :

const [err, data] = yield fs.readFile(filePath, "utf-8", callback);

6
задан Rusty 21 April 2015 в 10:43
поделиться

2 ответа

A DbContext должен жить для одной бизнес-операции (единицы работы), не более того. Бизнес-транзакция обычно представляет собой запрос, страницу или форму.

Вам действительно нужно прочитать документацию по Entity Framework: Работа с DbContext .

Я бы не создал экземпляр для каждого репозитория, поскольку бизнес-транзакция может управлять несколькими репозиториями.

Вы можете вставить контекст в свой репозиторий:

public class BaseRepository
{
    private IConfigurationContext context;
    public BaseRepository(IConfigurationContext context)
    {
        this.context = context;
    }
    //...
}

Измените свой завод, чтобы он каждый раз создавал экземпляр:

public interface IConfigurationContextFactory
{
    IConfigurationContext CreateContext();
}

// ...
public ConfigurationContext CreateContext()
{
    return new ConfigurationContext(connectionString);
}

Затем настройте свой преобразователь зависимостей, чтобы ввести IConfigurationContext на единицу работы. Предположим, вы работаете над приложением ASP.NET, используя единство.

container.RegisterType<IConfigurationContext>(
    //Instance per http request (unit of work)
    new PerRequestLifetimeManager(),
    //Create using factory
    new InjectionFactory(c => c.Resolve<IConfigurationContextFactory>.CreateContext()));

Не забудьте позвонить SaveChangesAsync в конце вашей бизнес-транзакции, когда это необходимо: операция выполнена успешно, а модификации должны быть сохраняется.

8
ответ дан Guillaume 28 August 2018 в 19:00
поделиться

У меня есть singleton context

Это ваша проблема. DbContext не является потокобезопасным и предназначен для выполнения одного запроса за раз. Поскольку вы делитесь своим DbContext, вы, вероятно, пытаетесь одновременно вызвать другой запрос, который не является «законным» в терминах DbContext.

Вы даже можете увидеть его в замечания ToListAsync :

Несколько активных операций в одном экземпляре контекста не поддерживаются. Используйте 'await', чтобы убедиться, что какие-либо асинхронные операции были выполнены до вызова другого метода в этом контексте.

То, что вы должны делать, не повторяет использование вашего контекста с глобальный синглтон, создавая новый контекст каждый раз, когда вы хотите запросить свою базу данных.

Изменить:

Вместо того, чтобы получить один Context по вашему заводскому методу, просто выделите новый для каждого запроса:

using (var context = new ConfigurationContext(connectionString))
{
    var query = await (from feature in context.Features
                join featureFlag in context.FeatureFlags
                on feature.FeatureId equals featureFlag.FeatureId
                into allFeatures
                from featureFlagValue in allFeatures.DefaultIfEmpty()
                where featureFlagValue.TenantId == tenantId
                select new BusinessEntities.FeatureFlag
                {
                   Code = feature.Code,
                   Type = feature.Type,
                   FeatureFlagId = featureFlagValue == null ? 0 : featureFlagValue.FeatureFlagId
                }).ToListAsync();
}
21
ответ дан Yuval Itzchakov 28 August 2018 в 19:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: