在cosmosdb中创建文档时被取消

时间:2019-02-20 18:01:15

标签: c# asp.net-core azure-cosmosdb

我们正在使用cosmosdb记录我们的应用程序日志。我们的日志有两层,一层是常规日志,另一层是常规日志的更详细信息。我们还将这些副本的副本记录在其他两个集合中以进行备份。因此,我们总共有四个集合。在我们的代码中,我们使用Async CreateDocumentAsync创建这些日志。我们将Task存储在列表中,并使用Task.WaitAll完成所有任务。在开发环境中,我们没有看到任何错误,但是在生产环境中,创建新文档时,我们在应用程序见解中看到了已取消的错误。下面的示例图片。

Error info from application insights of API

下面是我们正在使用的代码结构

API控制器代码

public void Log(LogModel logObject)
{
    try
    {
        _context.Save(logObject);
    }
    catch(Exception ex)
    {
        _azureTelemtry.TrackTrace($"Exception occured: {ex.ToString()}");
    }
}

上下文保存方法

public void Save(LogModel logObject)
{
    List<Task> saveTasks = new List<Task>();
    LogInfo logInfo = logObject.logInfo;
    LogDetails logDetails = logObject.logDetails;
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, primaryLogInfoCollectionID), logInfo));
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, archieveLogInfoCollectionID), logInfo));    
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, primaryLogDetailsCollectionID), logDetails));
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, archieveLogDetailsCollectionID), logDetails));
    Task.WaitAll(saveTasks.ToArrays());
}

异常详细信息

  

System.AggregateException:在   MyApplication.Logging.Controllers.ApiController.Log   (MyApplication.Logging,版本= 2.0.0.0,文化=中性,   PublicKeyToken = nullMyApplication.Logging,版本= 2.0.0.0,   文化=中性,PublicKeyToken =空:   C:\ TFS \ CA \ Logging \ Release \ Release   3.0-Hotfix \ Logging \ Controllers \ ApiController.csMyApplication.Logging,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = null:57)在   lambda_method(匿名托管的DynamicMethods程序集,   版本= 0.0.0.0,文化=中性,PublicKeyToken =空)在   Microsoft.Extensions.Internal.ObjectMethodExecutor + <> c__DisplayClass33_0.b__0   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker + d__12.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker + d__10.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker + d__14.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker + d__22.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker + d__17.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker + d__15.MoveNext   (Microsoft.AspNetCore.Mvc.Core,版本= 2.0.2.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Builder.RouterMiddleware + d__4.MoveNext   (Microsoft.AspNetCore.Routing,Version = 2.0.1.0,Culture = neutral,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware + d__11.MoveNext   (Microsoft.AspNetCore.Server.IISIntegration,版本= 2.0.1.0,   文化=中立,PublicKeyToken = adb9793829ddae60)   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware + d__3.MoveNext   (Microsoft.AspNetCore.Hosting,版本= 2.0.1.0,文化=中性,   PublicKeyToken = adb9793829ddae60),网址为   System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess   (System.Private.CoreLib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = 7cec85d7bea7798e),网址为   Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame`1 + d__2.MoveNext   (Microsoft.AspNetCore.Server.Kestrel.Core,版本= 2.0.1.0,   Culture = neutral,PublicKeyToken = adb9793829ddae60)内部异常   System.Threading.Tasks.TaskCanceledException在以下位置处理   MyApplication.Logging.Controllers.ApiController.Log:

1 个答案:

答案 0 :(得分:0)

您不等待任务。除了Save功能是同步的,因此Task.WaitAll(saveTasks.ToArrays()); runs synchronpusly

至少我希望public void Save(LogModel logObject)public Task Save(LogModel logObject),而Task.WaitAll(saveTasks.ToArrays());return Task.WhenAll(saveTasks.ToArrays());

public Task Save(LogModel logObject)
{
    List<Task> saveTasks = new List<Task>();
    LogInfo logInfo = logObject.logInfo;
    LogDetails logDetails = logObject.logDetails;
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, primaryLogInfoCollectionID), logInfo));
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, archieveLogInfoCollectionID), logInfo));    
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, primaryLogDetailsCollectionID), logDetails));
    saveTasks.Add(documentClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(DatabaseId, archieveLogDetailsCollectionID), logDetails));

    return Task.WhenAll(saveTasks.ToArrays());
}

如果您打算执行任务并忘记,现在可以使用_context.Save(logObject);,否则需要使用Task

另一个问题是:上面的代码打开了4个任务,并且无法控制地处理它。 .Net Core中的默认并发执行限制为10。现在认为Save方法一个接一个地调用了3次,但尚未完成。这意味着您需要有12个并发任务。但是.Net Core的限制为10个。我相信最后两个任务将被取消。