C#Windows服务 - 此关键字错误

时间:2015-12-06 19:04:07

标签: c# windows visual-studio

我在Windows窗体应用程序中使用以下代码时工作正常,但是我写的应用程序需要作为Windows服务运行,当我将代码移到Windows服务模板中时Visual Studio 2015社区版,我收到以下错误。

  

无法隐式转换类型" MyWindowsService.Main" to" System.ComponentModel.ISynchronizeVoke"。存在显式转换(您是否错过了演员?)

有没有人可以解释为什么我会收到这个错误,以及我需要做些什么来解决它?

抛出错误的代码是下面的行,它位于我的主类OnStart方法中(名为Main.cs)。该代码用于创建DataSubscriber类(AdvancedHMI库)的实例。

dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;

它必须与代码在Windows服务模板中的事实有关,因为使用this在运行相同代码的表单应用程序中完美地工作。

更新

更正,我尝试将其强制转换为所需类型,现在运行时出现以下错误。

  

其他信息:无法投射类型' MyWindowsService.Main'输入' System.ComponentModel.ISynchronizeInvoke'。

代码:

dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;

更新

我已经从我的Windows服务应用程序中包含了Main.cs文件的全部内容。

using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;

namespace PLCHistoricDataHarvester {
    public partial class Main : ServiceBase {
        private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
        private globals globals = new globals();
        private Dictionary<String, String> operationLines = new Dictionary<String, String>();
        private Dictionary<String, String> tags = new Dictionary<String, String>();
        private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
        private int harvesterQueueCount = 0;
        private string harvesterInsertValues = String.Empty;

        public Main() {
            InitializeComponent();
        }

        protected override void OnStart(string[] args) {
            // Initialize our harvester program
            initializeHarvester();

            Console.WriteLine("The program has started");
        }

        protected override void OnStop() {
            // Call code when the service is stopped
            Console.WriteLine("Program has stopped");
            Console.ReadLine();
        }

        public void initializeHarvester() {
            // First, we connect to the database using our global connection object
            globals.dbConn.DatabaseName = "operations";

            if (!globals.dbConn.IsConnect()) {
                // TODO: Unable to connect to database.  What do we do?
            }

            // Second, we connect to the database and pull data from the settings table
            globals.initializeSettingsMain();

            // Set IP address of PLC
            commObject.IPAddress = globals.getSettingsMain("Processor_IP");

            // Pull distinct count of our parent tags (Machines ex: Line 1, etc)
            operationLines = globals.getOperationLines();

            // If we have at least 1 operation line defined...we continue
            if (operationLines.Keys.Count > 0) {
                //Now we loop over the operation lines, and pull back the data points
                int dataSubscriberIndex = 0;

                foreach (KeyValuePair<String, String> lines in operationLines) {
                    int line_id = int.Parse(lines.Key);
                    string name = lines.Value;
                    tags = globals.getTags(line_id);

                    // If we have at least 1 tag for this operation line, we continue...
                    if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
                        // Create our dataSubscriber object
                        dataSubscribers.Add(new DataSubscriber());
                        dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
                        dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
                        dataSubscribers[dataSubscriberIndex].PollRate = 1000;
                        dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
                        dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
                        // Increment our dataSubscriberIndex
                        dataSubscriberIndex++;
                    }
                }
            }
        }

        private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
            // code removed as it is irrelevant 
        }
    }
}

2 个答案:

答案 0 :(得分:2)

错误消息说明:

  

存在显式转换(您是否错过了演员?)

所以添加这样的演员:

dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
                                                           ^^^^^^^^^^^^^^^^^^^^
                                                           //Add this

答案 1 :(得分:1)

如果您有控制台应用程序,将其转换为Windows服务的最简单方法是使用Topshelf,这是一个nuget包,可让您以控制台模式或非服务模式运行。 / p>

Here's the quickstart guide

我们一直用它来写服务,它可以帮助你避免这种脆弱的诡计。