【问题标题】:Windows Service AggregateException at Production Server生产服务器上的 Windows 服务 AggregateException
【发布时间】:2019-10-30 11:16:01
【问题描述】:

我们开发了一个 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
}

【问题讨论】:

  • 您的错误是由您未等待的任务中引发的异常引起的。您需要展示更多代码。
  • @Nick 我更新了我的帖子我添加了更多代码
  • // Push Notofication HERE 你有没有机会在那里调用异步方法?比如,返回一个任务?
  • public static async Task SendPushMessage(string deviceToken, string message) @Nick 方法的签名

标签: c# multithreading windows-services


【解决方案1】:

所以,根据你的cmets,你在notificationTimer_Elapsed中调用如下方法:

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

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

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

async void notificationTimer_Elapsed(...)

并使用await 调用SendPushMessage

【讨论】:

  • 感谢您的帮助我会尝试一下,但是为什么尽管我在我的设备上安装了该服务并且没有出现此问题,但为什么会在生产环境中发生这种情况?? @尼克
  • 因为显然在生产中 SendPushMessage 会引发异常,并且它不会在您的设备上。如果您按照建议修改代码,您将能够正确捕获并记录异常,并深入了解原因的细节。由于任务抛出AggregateException,请务必同时记录InnerException
猜你喜欢
  • 2012-08-03
  • 1970-01-01
  • 2014-05-16
  • 2012-02-19
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多