【问题标题】:canceled while creating documents in cosmosdb在 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:

【问题讨论】:

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


    【解决方案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 个限制。我相信最后两个任务会被取消。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多