我们正在使用cosmosdb记录我们的应用程序日志。我们的日志有两层,一层是常规日志,另一层是常规日志的更详细信息。我们还将这些副本的副本记录在其他两个集合中以进行备份。因此,我们总共有四个集合。在我们的代码中,我们使用Async CreateDocumentAsync创建这些日志。我们将Task存储在列表中,并使用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 =空: 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:
答案 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个。我相信最后两个任务将被取消。