c# - 生产服务器上的 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
}
解决方案
因此,根据您的评论,您在中调用以下方法notificationTimer_Elapsed
:
public static async Task SendPushMessage(string deviceToken, string message)
这是一个异步方法。当您在不使用的情况下调用它时await
,您基本上会一劳永逸地调用它,并且您无法再捕获它的异常。这些异常将以您看到的形式传播。
要解决您的问题,请将 notificationTimer_Elapsed 标记为async
:
async void notificationTimer_Elapsed(...)
并用于await
调用SendPushMessage
.
推荐阅读
- excel - 如何修改此代码以引用不同工作表中的单元格
- hyperledger-fabric - 带有 Node SDK 的 Hyperledger 2.1:无法调用链代码
- join - 带有聚合错误的 ksqlDB 流连接表
- ormlite - 如何在 ORMLite Android 中存储 byte[]?
- node.js - Express JS / MongoDB
- javascript - 继续在移动设备上以“屏幕关闭/背景”运行 WebApp
- java - Swagger - 日期时间字段的误导性样本值,我该如何解决这个问题?
- c# - 在 C# 中,是否可以重构我的 Post 和 Put 方法以消除代码重复?
- javascript - 了解柏树时钟()和滴答()
- angular - 将标签路由到子级