简体   繁体   English

WindowsService的OnStart方法中SynchronizationContext为null

[英]SynchronizationContext is null in OnStart method of WindowsService

I am trying to create a background Task for my windows service (it is already installed via InstallUtil.exe) and use SynchronizationContext to send some messages to the main Service thread. 我正在尝试为Windows服务(已通过InstallUtil.exe安装)创建后台任务,并使用SynchronizationContext将一些消息发送到主服务线程。

Unfortunately SynchronizationContext.Current is always null on service start. 不幸的是, SynchronizationContext.Current在服务启动时始终为null

I've saw some questions around the topic and hints on why SynchronizationContext is null in various scenarios (eg in Winforms, WPF apps) but no clue about the Windows services. 我已经看到了有关该主题的一些问题,并暗示了在各种情况下(例如,在Winforms,WPF应用程序中)为什么SynchronizationContext为null,但对Windows服务却一无所知。

How can I resolve this issue? 我该如何解决这个问题? Below the code: 代码下方:

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.
        }
    }
}

Console and Service applications do not have a default SynchronizationContext. 控制台和服务应用程序没有默认的SynchronizationContext。 This is because there is no "UI" thread that is pumping messages constantly while the application runs. 这是因为没有“ UI”线程在应用程序运行时不断地抽取消息。

The question is why do you need a synchronization context? 问题是为什么您需要同步上下文?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM