Я пытаюсь создать фоновую задачу для моей службы Windows (она уже установлена через InstallUtil.exe) и использую SynchronizationContext для отправки некоторых сообщений в основной поток службы.
К сожалению, SynchronizationContext.Current
всегда null
при запуске службы.
Я видел несколько вопросов по этой теме и подсказки о том, почему SynchronizationContext имеет значение null в различных сценариях (например, в Winforms, приложениях WPF), но не имею представления о службах 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.
}
}
}