我尝试使用C#创建一个Windows服务。服务必须在5089端口上打开TCPListener并开始调度命令。但是,如果我将我的TCPListener初始化代码和开始调度线程放入OnStart()服务方法,我的服务无法启动(管理面板 - >管理 - >服务 - >我的服务 - >开始)
protected override void OnStart(string[] args)
{
_server = new CommandServer("LocalCommandServer", "192.168.10.150", false);
_server.Initialize("LocalCommandServer", "192.168.10.150"); // In this method starts dispatching thread
}
protected override void OnStop()
{
_server.Dispose();
}
如何在Windows服务中启动TCPListener
和调度线程?
public class CommandServer : IDisposable
{
private IPAddress _serverIP;
private bool _mayDispatch;
public string Name { get; set; }
private Queue<string> _commandsQueue;
private TcpListener _commandListener;
private Thread _commandListenerThread;
private Thread _mainThread;
public CommandServer(string name, string serverIP, bool initialize)
{
if (initialize)
Initialize(name, serverIP);
}
public bool Initialize(string name, string serverIP)
{
_serverIP = IPAddress.Parse(serverIP);
_mayDispatch = true;
Name = name;
_commandsQueue = new Queue<string>();
_commandListener = new TcpListener(_serverIP, 5089);
_commandListenerThread = new Thread(TcpListenerThread);
_commandListener.Start();
_commandListenerThread.Start();
_mainThread = Thread.CurrentThread;
StartDispatching();
return true;
}
private void StartDispatching()
{
while (_mayDispatch)
{
if (_commandsQueue.Count > 0)
DispatchCommand(_commandsQueue.Dequeue());
}
_commandListener.Stop();
_commandListenerThread.Abort();
}
public void DispatchCommand(string cmnds)
{
var cmnd = cmnds.Split(' ');
switch (cmnd[0].ToLower())
{
case "terminate":
_mayDispatch = false;
break;
case "start":
var proc = new Process
{
StartInfo =
{
FileName = cmnd[1],
CreateNoWindow = false,
UseShellExecute = true
}
};
proc.Start();
break;
}
}
public void TcpListenerThread()
{
while (true)
{
var client = _commandListener.AcceptTcpClient();
if (client.Connected)
{
var clientStream = client.GetStream();
var buff = new List<byte>();
while (clientStream.CanRead)
{
var b = clientStream.ReadByte();
if (b == -1)
break;
buff.Add((byte)b);
}
var command = Encoding.ASCII.GetString(buff.ToArray());
_commandsQueue.Enqueue(command);
System.Diagnostics.Debug.WriteLine("Queued: " + _commandsQueue.Count);
}
else
{
System.Diagnostics.Debug.WriteLine("Not connected");
}
}
}
public void Dispose()
{
_commandListener.Stop();
_commandListenerThread.Abort();
}
}
答案 0 :(得分:1)
TCPListener初始化代码可能会抛出一些异常,尝试通过将Debugger.Launch()
作为OnStart
中的第一个语句来调试您的服务,并查看那里发生的事情。
答案 1 :(得分:0)
您需要从OnStart事件返回。
在此处查看示例http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx
答案 2 :(得分:0)
我找到了它!
protected override void OnStart(string[] args)
{
_server = new CommandServer("LocalCommandServer", "192.168.10.150", false);
_serverThread = new Thread(ServerThread);
_serverThread.Start();
}
private void ServerThread()
{
_server.Initialize("LocalCommandServer", "192.168.10.150");
}
protected override void OnStop()
{
_serverThread.Abort();
_server.Dispose();
}