Описание проблемы
Мы развернули нашего чат-бота в облаке Azure в качестве службы приложений, и в Application Insights мы видим несколько исключений типа TaskCanceledException
, которые появляются случайным образом.
После принятияПосмотрите журналы, которые мы определили три строки кода, которые бросают исключения.Я отметил их как TaskCanceledException source #
.Вот упрощенная структура нашего контроллера обмена сообщениями для справки:
public async Task<IHttpActionResult> Post([FromBody]BotActivity activity)
{
try
{
var result = await PostInternal(activity).ConfigureAwait(false);
return result;
}
catch (Exception e)
{
Logger.Error(e);
throw;
}
}
private async Task<IHttpActionResult> PostInternal(BotActivity activity)
{
// TaskCanceledException source #1.
await SendTypingIndicator(activity).ConfigureAwait(false);
var type = activity.GetActivityType();
if (type == ActivityTypes.Message)
{
// TaskCanceledException source #2.
var flag = await LoadFlagFromBotState(activity).ConfigureAwait(false);
// Some logic slightly altering flow according to value of 'flag'.
// TaskCanceledException source #3.
await Conversation.SendAsync(activity, () => new RootDialog()).ConfigureAwait(false);
}
return Ok();
}
private async Task SendTypingIndicator(BotActivity activity)
{
var reply = activity.CreateReply();
reply.Type = ActivityTypes.Typing;
reply.Text = null;
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply).ConfigureAwait(false);
}
private async Task<bool> LoadFlagFromBotState(BotActivity activity)
{
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = Address.FromActivity(activity);
var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None).ConfigureAwait(false);
var flag = userData.GetProperty<bool>("TheFlag");
if (!flag)
{
userData.SetProperty("TheFlag", true);
await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None).ConfigureAwait(false);
await botDataStore.FlushAsync(key, CancellationToken.None).ConfigureAwait(false);
}
return flag;
}
}
А вот URL внешних зависимостей, время ожидания которых истекло в соответствии с Application Insights:
- Для
TaskCanceledException source #1
: - Для
TaskCanceledException source #2
: - Для
TaskCanceledException source #3
:
Дополнительная информация
- Наш бот размещен в качестве службы приложений в облаке Microsoft Azure.
- Мы подключили собственный менеджер BotState в соответствии с следующей документацией , чтобы все BotState хранилось вCosmos DB.
- Наш экземпляр Cosmos DB находится в той же группе ресурсов Azure, что и служба приложений бота.
- Мы проверили доступность и пропускную способность нашего экземпляра Cosmos DB, и, кажется, все в порядке..
- Мы используем DirectLine в качестве канала связи.
TaskCanceledException
происходит случайным образом, и, похоже, нет никаких конкретных шагов, которые необходимо выполнить, чтобы воспроизвести это. - Мы попытались адаптировать шаблон
async-await
«надлежащим образом», например, убедившись, что мыне смешивать синхронизирующий и асинхронный код и использовать ConfigureAwait (false) везде, где находится ключевое слово await
.
Заключение
Мы пытались выяснить первопричинунекоторое время, однако, мы понятия не имеем, в чем может быть проблема здесь.Мы исключили проблемы с сетью из-за того, что здесь мы используем PaaS Azure.
Буду признателен за любой совет.