【问题标题】:.NET Core 2.2 time.ToString("d", culture) Exception.NET Core 2.2 time.ToString("d",culture) 异常
【发布时间】:2020-04-27 22:30:30
【问题描述】:

我有一个很奇怪的情况,mydatetime.ToString("d",culture) 有时会抛出异常。

这是在 .Net Core 2.2 上的 Azure 中运行的简单 Azure Premium 功能 V2。它是存储队列的触发器。此触发器每月处理约 250 万次。有时 ToString 会抛出 'External component has throw an exception';

try {
 var culture = new System.Globalization.CultureInfo(order.Address.Country.CultureCode);

 var date = order.CreatedDate;

 var test = date.ToString("d", culture); //This throws exceptions.
} catch (Exception exception) {
 await StaticLoggers.HandleExceptionAsync(new BaseServices.Models.ExceptionModel {
  Environment = "CustomException",
   Message = $ "{order.CreatedDate.MyToDateString()} {order.Address.Country.CultureCode} " + exception.Message.MyToStringTrim(),
   StackTrace = exception.StackTrace.MyToStringTrim()
 });

 return null;
}

从日志来看,异常是完全随机的,有时一天没有错误,有时大约 1000 个。我观察到的是,它在高峰期确实会抛出更多,所以我最好的猜测是这与 Azure 中的并行执行有关。此外,当异常出现时,日期和文化会有所不同,所以我也怀疑这不是错误的原因。 这是我在 ToString 抛出异常时记录的消息。

2020/01/10 01:10:24 de-DE External component has thrown an exception.

日期永远不会为空,并且始终存在真实的文化。如果我注释 ToString 行,则不会发生错误。

堆栈跟踪:

at Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, String lpLocaleName, UInt32 Calendar, String lpReserved, UInt32 CalType, Void* lParam) 
at System.Globalization.CalendarData.GetCalendars(String localeName, Boolean useUserOverride, CalendarId[] calendars) at System.Globalization.CultureData.get_CalendarIds() 
at System.Globalization.DateTimeFormatInfo.set_Calendar(Calendar value) 
at System.Globalization.CultureInfo.get_DateTimeFormat() at System.DateTimeFormat.Format(DateTime dateTime, String format, IFormatProvider provider, TimeSpan offset) 
at System.DateTimeFormat.Format(DateTime dateTime, String format, IFormatProvider provider) 
at Automation.ProcessOrderEvent.EventService.EventWorkflowService.GetOrderAsync(Int32 orderId) in C:\...\EventService\OrderUpdated.cs:line 328

更新 1: 上面的错误消息是完整的堆栈跟踪,出于安全原因,除了物理路径外,没有任何内容被删除或编辑。 这是顶层的样板。

using BusinessLogicLayer.Services;
using BusinessLogicLayer.Services.Interfaces;

[assembly: WebJobsStartup(typeof(Startup))]
namespace Automation.ProcessOrderEvent
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddMemoryCache();
            builder.Services.AddScoped<IOrderService, OrderService>();
        }
    }

    public class ProcessOrderEvent
    {
        private readonly IOrderService _orderService;

        public ProcessOrderEvent(IOrderService orderService) => _orderService = orderService;

        [FunctionName("ProcessAwesomeEvent")]
        public async Task Run([QueueTrigger("eventqueue", Connection = "AzureWebJobsStorage")] string myQueueItem, ExecutionContext context, ILogger logger)
        {
            await _orderService.ProcessOrderUpdate(myQueueItem);
        }
    }
}

这是订单服务的代码:

public partial class EventWorkflowService
{
    public async Task ProcessOrderUpdate(orderId)
    {
        var order = await GetOrderAsync(orderId);
        if (order == null)
            return;

        var date = order.CreatedDate.ToString("d", new CultureInfo(order.Address.Country.CultureCode));
        //rest of the code
    }
}

GetOrder 是一个简单的 System.Data.SqlClient 查询,它获取数据并将它们绑定到订单模型。

【问题讨论】:

  • 嗨,爱德华,请问您是如何获得“订单”的(我想检查您提供的 try catch 代码上方的代码)?你能请你完整的错误信息吗?
  • 上面的错误信息是完整的堆栈跟踪,出于安全原因,除了物理路径外,没有任何内容被删除或编辑。我还用更多代码更新了帖子。
  • 该堆栈跟踪中的顶部框架与您的代码无关,因此这似乎是 .NET Core 2.2 中的一个错误 - 我会将其归档在 github.com/dotnet/corefx
  • 您好 Edward,请问您的问题是否已解决?如果解决方案对您的问题有帮助,请accept作为答案(单击答案旁边的复选标记将其从灰色切换为已填充),谢谢~
  • 这还没有解决,我有自己的解决方案,我正在测试。如果它有效,我会更新帖子。

标签: c# .net azure-functions asp.net-core-2.2


【解决方案1】:

根据报错信息,我们可以找到一行:

at System.DateTimeFormat.Format(DateTime dateTime, String format, IFormatProvider provider)

但“DateTimeFormat”只存在于 .net 2.2 的“System.Globalization.CultureInfo”中

您的错误消息中的另一行是:

at System.Globalization.CultureInfo.get_DateTimeFormat() at System.DateTimeFormat.Format(DateTime dateTime, String format, IFormatProvider provider, TimeSpan offset)

所以我认为这可能会导致错误消息,这两个“DateTimeFormat”不匹配。

由于我看不到您的所有代码和功能,所以我只能提供这些信息,我怀疑这可能是您参考的原因。请检查您的代码并注意代码中的“DateTimeFormat”(也许当您从 sql 获取订单时,我猜从 sql 获取“DateTimeFormat”是“System.DateTimeFormat”,当您新建“CultureInfo ”,如果可以在 .net 2.2 中使用“System.Globalization.CultureInfo.DateTimeFormat”)。

【讨论】:

    【解决方案2】:

    我通过将解决方案从 .NET Core 2.2 和 Functions V2 升级到 .NET Core 3.1 和 Azure 函数到 V3 解决了这个问题。 自从升级后我再也没有看到过这个 bug,所以我最好的猜测是它是 ether .NET Core 2.2 或 Azure function V2 的 bug。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-20
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      相关资源
      最近更新 更多