#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)
.