我们已将聊天机器人作为应用程序服务部署到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;
}
}
以下是根据Application Insights超时的外部依赖项的URL:
TaskCanceledException source #1
:
https://directline.botframework.com/v3/conversations/<CONV_ID>/activities/<ACT_ID>
TaskCanceledException source #2
:
https://docdb-instance-url.documents.azure.com/dbs/<DB_NAME>/colls/BotState/docs/directline:user<USER_ID>
TaskCanceledException source #3
:
https://docdb-instance-url.documents.azure.com/dbs/<DB_NAME>/colls/BotState/docs/directline:private<CONV_ID>:<USER_ID>
https://docdb-instance-url.documents.azure.com/dbs/<DB_NAME>/colls/BotState/docs/directline:conversation<CONV_ID>
https://docdb-instance-url.documents.azure.com/dbs/<DB_NAME>/colls/BotState/docs/directline:user<USER_ID>
TaskCanceledException
随机发生,似乎不需要执行任何特定步骤来重现此内容。async-await
模式,例如,确保不混合任何同步和异步代码,并在await
的所有地方使用ConfigureAwait(false)关键字是。一段时间以来,我们一直在试图找出根本原因,但是我们不知道这里可能是什么问题。由于这里使用了Azure的PaaS,因此排除了网络问题。
我将不胜感激。