我在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
}
}
}
答案 0 :(得分:2)
错误消息说明:
存在显式转换(您是否错过了演员?)
所以添加这样的演员:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
^^^^^^^^^^^^^^^^^^^^
//Add this
答案 1 :(得分:1)
如果您有控制台应用程序,将其转换为Windows服务的最简单方法是使用Topshelf,这是一个nuget包,可让您以控制台模式或非服务模式运行。 / p>
我们一直用它来写服务,它可以帮助你避免这种脆弱的诡计。