繁体   English   中英

WindowsService的OnStart方法中SynchronizationContext为null

[英]SynchronizationContext is null in OnStart method of WindowsService

我正在尝试为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.
        }
    }
}

控制台和服务应用程序没有默认的SynchronizationContext。 这是因为没有“ UI”线程在应用程序运行时不断地抽取消息。

问题是为什么您需要同步上下文?

暂无
暂无

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

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