Некоторый код C # приводит к сообщению об ошибке «Сервер занят»

#c# #.net #async-await #task #vsto

#c# #.net #асинхронный-ожидание #задача #vsto

Вопрос:

Следующий код:

(Вызов асинхронного метода, возвращающего задачу)

 ...
        Task<int> taskInt = Globals.ThisAddIn._DAL.InsertTestAceQL();
        int resInt = taskInt.Resu<
        MessageBox.Show("resInt= "   resInt.ToString());
...
        public async Task<int> InsertTestAceQL()
        {
            int res = int.MinValue;
            try
            {
                string sql = "INSERT INTO dbo.AceQLTst2 VALUES ('From Visio')";

                AceQLCommand command = new AceQLCommand(sql, AceQLConn().Result);
                try
                {
                    res = await command.ExecuteNonQueryAsync();
                }
                catch (AceQLException ex)
                {
                    Globals.ThisAddIn.HandleException(ex.Message);
                }
            }
            catch (Exception ex)
            {
                Globals.ThisAddIn.HandleException(ex.Message);
            }

            return res;
        }
...
  

приводит к следующему сообщению об ошибке:

И код просто застрял.

Сервер занят

Кто-нибудь знает что-нибудь, пожалуйста?

Комментарии:

1. Попробуйте перезапустить свой сервер и запустить код снова.

2. .Result это неправильный способ доступа к результату асинхронной операции. Один из них вызывает взаимоблокировку.

3. @Arsen, это не помогает. Кстати, тот же код, который хорошо работает в «Консольном приложении», но плохо работает с надстройками Visio «Библиотеки классов».

4. @GalTzemach, извините, сообщение «… занято» наводит меня на мысль, что основной причиной может быть зависание приложения. Работает ли ваше тестовое подключение к базе данных, как ожидалось? Вы также пытались ввести какое-нибудь реальное число int вместо int.MinValue ? Можете ли вы получить некоторые значения из базы данных с помощью запроса или только вставка завершается неудачей? Попробуйте ответить на эти вопросы, надеюсь, они смогут помочь.

5. «Сообщение об ошибке появляется только тогда, когда я пытаюсь это сделать во время работы с потоком пользовательского интерфейса» — Это совсем другой контекст, и именно это различие является причиной проблемы. Дело в том, что вам нужно выполнить надлежащие await действия, чтобы получить результат. Если вы не используете метод, отмеченный async , вам нужно провести некоторое исследование. Вызов .GetAwaiter().GetResult() все еще может привести к взаимоблокировке в зависимости от того, что еще запланировано в потоке. Прочитайте все, что вы можете об асинхронности, Стивена Клири .

Ответ №1:

Ни один код C # не приводит к тому, что какой-либо сервер занят.

Что происходит, так это то, что пользовательский интерфейс заблокирован этим кодом:

 int resInt = taskInt.Resu<
  

и Windows сообщает вам, что приложение занято и не отвечает — заблокирован пользовательский интерфейс.

Комментарии:

1. Спасибо. Итак, каков правильный способ вызвать и дождаться результата асинхронного метода из неасинхронного (обычного) метода?

2. В async методе и с await помощью. И у всех await в InsertTestAceQL должно быть ConfigureAwait(false) .