我正在尝试为Windows服务(已通过InstallUtil.exe安装)创建后台任务,并使用 SynchronizationContext 将一些消息发送到主服务线程。
不幸的是,SynchronizationContext.Current
在服务启动时始终是null
。
我已经看到了有关该主题的一些问题,并暗示了为什么在各种情况下(例如Winforms,WPF应用程序中)SynchronizationContext为null,却对Windows服务一无所知。
如何解决此问题? 代码下方:
using Lextm.SharpSnmpLib.Messaging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SnmpTrapListenerService
{
public partial class SnmpTrapListenerService : ServiceBase
{
public Listener Listener { get; set; }
public CancellationTokenSource CancellationTokenSource { get; set; }
public Task PulseTask { get; set; }
public SynchronizationContext SyncContext { get; set; }
public SnmpTrapListenerService()
{
//Debugging windows service.
Debugger.Launch();
InitializeComponent();
Debug.WriteLine($"Main service threadId: {Thread.CurrentThread.ManagedThreadId}");
}
protected override void OnStart(string[] args)
{
try
{
CancellationTokenSource = new CancellationTokenSource();
SyncContext = SynchronizationContext.Current; //Here I'm getting always null.
PulseTask = new Task(x =>
{
Debug.WriteLine($"Pulse task threadId: {Thread.CurrentThread.ManagedThreadId}");
while (true)
{
var context = (SynchronizationContext)x;
context.Post(new SendOrPostCallback(y => DoSomethingOnServiceMainThread()), null);
Debug.WriteLine($"Alive at {DateTime.Now.ToLongTimeString()}");
Thread.Sleep(5000);
}
}, SyncContext, CancellationTokenSource.Token);
PulseTask.Start();
Listener = new Listener();
Listener.AddBinding(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 162)); //IP address of listener system
Listener.MessageReceived += Listener_MessageReceived;
Listener.StartAsync();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
Debug.WriteLine("Service started");
}
private static void Listener_MessageReceived(object sender, MessageReceivedEventArgs e)
{
File.AppendAllText("servicelog.log", "Version :" + e.Message.Version + "\n");
File.AppendAllText("servicelog.log", "Version :" + e.Message.Scope.Pdu.Variables[4].Data.ToString() + "\n");
}
protected override void OnStop()
{
CancellationTokenSource.Cancel();
Listener.Stop();
Debug.WriteLine("Service stopped");
}
private void DoSomethingOnServiceMainThread()
{
//Some work that needs to be done one Service main thread.
}
}
}
答案 0 :(得分:1)
控制台和服务应用程序没有默认的SynchronizationContext。这是因为没有“ UI”线程在应用程序运行时不断地抽取消息。
问题是为什么您需要同步上下文?