在 cosmosdb 中创建文档时取消
Posted
技术标签:
【中文标题】在 cosmosdb 中创建文档时取消【英文标题】:canceled while creating documents in cosmosdb 【发布时间】:2019-07-14 12:19:04 【问题描述】:我们正在使用 cosmosdb 来记录我们的应用程序日志。我们的日志有两层,一层有一般信息,另一层有一般日志的更详细信息。我们还将这些副本记录在其他两个集合中以进行备份。所以我们有完整的四个集合。在我们的代码中,我们使用 Async CreateDocumentAsync 来创建这些日志。我们将任务存储在一个列表中,并使用 Task.WaitAll 来完成所有任务。在开发环境中,我们没有看到任何错误,但在生产环境中,我们在创建新文档时在应用程序洞察中看到取消的错误。下面的示例图片。
下面是我们使用的代码结构
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=null: C:\TFS\CA\Logging\Release\Release 3.0-Hotfix\Logging\Controllers\ApiController.csMyApplication.Logging,版本=2.0.0.0,Culture=neutral,PublicKeyToken=null: 57) 在 lambda_method(匿名托管的 DynamicMethods 程序集, 版本=0.0.0.0,文化=中性,PublicKeyToken=null) 在 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,版本=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.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】:您不等待任务。此外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 中默认的 Concurrent Execution Limit 是 10。现在想想Save
方法连续调用了 3 次,还没有完成。这意味着您需要有 12 个并发任务。但是 .Net Core 有 10 个限制。我相信最后两个任务会被取消。
【讨论】:
以上是关于在 cosmosdb 中创建文档时取消的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试使用 python 创建一个空白文档时,Google API 没有在驱动器中创建任何文档