首页 > 解决方案 > 生产服务器上的 Windows 服务 AggregateException

问题描述

我们开发了一个windows服务并在开发时使用它,在开发时安装和工作正常,当在生产端安装服务时,服务开始抛出聚合功能

以下是抛出异常的日志错误,仅在客户端的生产服务器上抛出

System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: 
Object reference not set to an instance of an object.
   at AutoLeaders.Infrastructure.ParseHelper.<GetInstallations>d__2.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at AutoLeaders.PushNotifications.PushNotificationsSender.notificationTimer_Elapsed(Object sender, ElapsedEventArgs e)
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
   at AutoLeaders.Infrastructure.ParseHelper.<GetInstallations>d__2.MoveNext()<---


System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at AutoLeaders.Infrastructure.ParseHelper.<GetInstallations>d__2.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1.get_Result()
   at AutoLeaders.PushNotifications.PushNotificationsSender.notificationTimer_Elapsed(Object sender, ElapsedEventArgs e)
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
   at AutoLeaders.Infrastructure.ParseHelper.<GetInstallations>d__2.MoveNext()<---

以下是代码示例

namespace AutoLeaders.PushNotifications
{
    public partial class PushNotificationsSender : ServiceBase
    {
        Timer _notificationTimer;
        // Keep track of the last processed id.
        int _lastProcessedId;

        public PushNotificationsSender()
        {
            InitializeComponent();

            AutoLog = false;

            eventLogComponent = new EventLog();
            if (!EventLog.SourceExists("AL Push Notifications"))
            {
                EventLog.CreateEventSource("AL Push Notifications", "AL add-on Services");
            }
            eventLogComponent.Source = "AL Push Notifications";
            eventLogComponent.Log = "AL add-on Services";
        }

        protected override void OnStart(string[] args)
        {
            _notificationTimer = new Timer();
            _notificationTimer.Elapsed += notificationTimer_Elapsed;
            _notificationTimer.Interval = 25 * 1000;
            _notificationTimer.Start();
            LogData.LogDataFile(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now));
            eventLogComponent.WriteEntry(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now), EventLogEntryType.Information, LogCodes.ServiceStarted);
        }

        public void OnDebug() 
        {
            _notificationTimer = new Timer();
            _notificationTimer.Elapsed += notificationTimer_Elapsed;
            _notificationTimer.Interval = 25 * 1000;
            _notificationTimer.Start();

            LogData.LogDataFile(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now));
            eventLogComponent.WriteEntry(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now), EventLogEntryType.Information, LogCodes.ServiceStarted);
            notificationTimer_Elapsed(null, null);
        }

        void notificationTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _notificationTimer.Enabled = false;

            try
            {
        // Code to handle timer 

                while (true)
                {
                    // Get installations from web service  
                   // Async function to call push notifications for mobile 

                }//while true
            }
            catch (Exception ex)
            {
                try
                {// it seems exception cached here 
                    File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "Log.txt", ex.ToString() + "\n\n");
                }
                catch
                {
                }
            }


            _notificationTimer.Enabled = true;

        }// notificationTimer
    }
}

更新

生产服务器是 Windows Server 2012 ,创建设置的 Visual Studio 是 Visual Studio 2019

这里有更多关于代码

  protected override void OnStart(string[] args)
    {

        _notificationTimer = new Timer();
        _notificationTimer.Elapsed += notificationTimer_Elapsed;
        _notificationTimer.Interval = 25 * 1000;
        _notificationTimer.Start();
        LogData.LogDataFile(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now));
        eventLogComponent.WriteEntry(string.Format("AL Push Notifications Service started at {0}.", DateTime.Now), EventLogEntryType.Information, LogCodes.ServiceStarted);
    }
    void notificationTimer_Elapsed(object sender, ElapsedEventArgs e)
    {

        _notificationTimer.Enabled = false;


        try
        {
            LogData.LogDataFile(string.Format("Job started (notificationTimer_Elapsed(sender,e)) at {0}.", DateTime.Now));
            // Get Installation Objects
            var skip = 0;
            var pageIndex = 1;
            var limit = 100;
            while (true)
            {
                Get Data //
                foreach (......)
                {
                    if (true)
                    {
                        foreach (......)
                        {
                            using (DataBaseContext)
                            {
                                if (lastTrackRecord.RecordDate > currentDate)
                                {
                                    if (true)
                                    {
                                        if (true)
                                        {

                                            // Push Notofication HERE 
                                        }
                                    }
                                }//if currentDate
                            }// end using

                        } // end if foreach

                    }// if engine
                    #endregion



                } // foreach installation

            }//while true
        }
        catch (Exception ex)
        {
            // Log Data                  
        }
        _notificationTimer.Enabled = true;
    }// notificationTimer
}

标签: c#multithreadingwindows-services

解决方案


因此,根据您的评论,您在中调用以下方法notificationTimer_Elapsed

public static async Task SendPushMessage(string deviceToken, string message)

这是一个异步方法。当您在不使用的情况下调用它时await,您基本上会一劳永逸地调用它,并且您无法再捕获它的异常。这些异常将以您看到的形式传播。

要解决您的问题,请将 notificationTimer_Elapsed 标记为async

async void notificationTimer_Elapsed(...)

并用于await调用SendPushMessage.


推荐阅读