Как вызывать процедуры хранения с помощью async и await в С#

Я использую версию сообщества Visual Studio 2015 и MVC 5, Entity Framework 6. Я только что узнал, как использовать асинхронность и ждать выполнения асинхронного вызова.

Теперь в моем проекте у меня есть только операции CRUD, и для всех операций я написал процедуры хранения, у меня нет больше бизнес-логики в моем API, кроме вызова процедур хранения. Поэтому я использую асинхронный режим и жду вызова процедуры хранения.

Но делая это, я получаю ошибку,

'int' does not contain a definition for 'GetAwaiter' and no extension method 'GetAwaiter' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)

Мой код,

 [HttpPost]
        public async Task<IHttpActionResult> AddContactEmails(Contacts data)
        {
            using (JodoDataEntities DB = new JodoDataEntities())
            {
                int Result = await DB.AddContacts(data.userId, data.data);
                return Ok();
            }
        }

Моя процедура хранения очень проста, я что-то возвращаю из нее, но EF принимает ее как тип возвращаемого значения int.

ALTER PROCEDURE [dbo].[AddContacts]
    @userId nvarchar(128),
    @contacts nvarchar(MAX)
AS
BEGIN
    SET NOCOUNT ON;
    if not exists(select top 1 * from Contacts where userId = @userId)
    begin
        insert into Contacts (userId, contacts) VALUES (@userId, @contacts)
    end
END

Код EF (генерируется автоматически),

 public virtual int AddContacts(string userId, string contacts)
        {
            var userIdParameter = userId != null ?
                new ObjectParameter("userId", userId) :
                new ObjectParameter("userId", typeof(string));

            var contactsParameter = contacts != null ?
                new ObjectParameter("contacts", contacts) :
                new ObjectParameter("contacts", typeof(string));

            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("AddContacts", userIdParameter, contactsParameter);
        }

1). Почему я получаю эту ошибку при вызове метода?

2). где мне нужно изменить, чтобы заставить его работать?

3). Так что мне действительно нужно использовать асинхронность и ждать, когда у меня есть только вызовы SP в моем API?


person Keval Patel    schedule 17.10.2015    source источник
comment
Поскольку ваши методы не являются ожидаемыми, вы должны обернуть их чем-то вроде Task.Run, если считаете, что вам нужно использовать async/await.   -  person Tieson T.    schedule 17.10.2015


Ответы (1)


Если это возвращает Task<int>:

DB.AddContacts(...);

Затем this просто возвращает int:

await DB.AddContacts(...);

Таким образом, переменная Result должна иметь тип int, а не Task<int>.


Редактировать: я только что заметил определение AddContacts() в вашем вопросе. Это не метод async, поэтому ждать его нельзя. В вашем коде нет async операций. Просто полностью удалите попытки async и await, это синхронный код...

int Result = DB.AddContacts(...);

Кстати, это плохая идея:

catch (Exception ex)
{
    throw ex;
}

Это в основном выбрасывает полезную отладочную информацию. Просто полностью удалите конструкцию try/catch и позвольте исключению быть выброшенным операцией, которая изначально его выдала.

person David    schedule 17.10.2015
comment
после написания вроде, int Result = await (DB.AddContacts(data.userId, data.data)); ..... выдает мне ошибку, и мы не можем вернуть int из асинхронного метода. Он должен аннулировать задачу или задачу‹T›. - person Keval Patel; 17.10.2015
comment
@KevalPatel: я только что заметил определение AddContacts() в вашем вопросе. Это... не async. Так что вы не можете await этого. Просто вызовите его как обычный метод, в этом коде нет async. - person David; 17.10.2015
comment
Я изменил некоторые вещи, о которых идет речь, пожалуйста, проверьте мой AddContactEmails(). И AddContacts() автоматически генерируется инфраструктурой сущностей. Вы хотите, чтобы я сделал это асинхронным? - person Keval Patel; 17.10.2015
comment
@KevalPatel: я не уверен, чего вы пытаетесь достичь в данный момент. В этом коде нет никаких асинхронных операций ввода-вывода. Таким образом, нет никаких причин для того, чтобы методы, использующие эти операции, были асинхронными. Если код EF имеет async версии своих операций, вы можете вызывать эти из использования async методов. - person David; 17.10.2015
comment
Я просто хочу делать асинхронные вызовы, поэтому для этого я использую асинхронность и ожидание, я все еще изучаю использование асинхронного ожидания. - person Keval Patel; 17.10.2015
comment
@KevalPatel: Но для того, чтобы быть асинхронной, основная операция должна быть асинхронной. Эта операция базы данных является синхронной. Когда EF генерирует код, создает ли он какие-либо асинхронные версии одних и тех же операций? - person David; 17.10.2015
comment
Я понимаю, о чем вы говорите. Можете ли вы сказать мне, как я могу сделать это асинхронным? Или мне нужно работать только с запросами LINQ? - person Keval Patel; 17.10.2015
comment
@KevalPatel: похоже, что может быть обходной путь или два: stackoverflow.com/questions/25901862/ - person David; 17.10.2015