У меня есть экземпляр следующего кода, который выполняется правильно в Debug или как отдельное приложение Windows:
TcpListener tcpListener = new TcpListener(IPAddress.Any, 4554);
tcpListener.Start();
while (true)
{
try
{
using (Socket socket = tcpListener.AcceptSocket())
{
// Code here is reached in Debug or as a Console Application
// but not as a Windows Service
}
}
catch (SocketException se)
{
// This is never reached
}
catch (Exception ex)
{
// This is never reached
}
finally
{
// This is never reached in the Windows Service
}
}
Однако, когда я устанавливаю его как службу Windows, он падает на tcpListener.AcceptSocket()
и записывает в Event Viewer следующее:
Необработанное исключение ("System.Net.Sockets.SocketException") произошло в MyService.exe [768]. "Отладка" Just-In-Time "при отладке этого исключения завершилась ошибкой со следующей ошибкой: попытка операции не поддерживается.
Даже пытаясь поймать исключение, я больше не могу регистрировать. Выполнение кода в Debug ничего не выполняет, потому что код успешно блокирует приложение и ждет клиентского соединения.
Есть ли способ реализовать это для службы Windows?
Совет usr (и этот ответ) привел меня к ошибке в коде. Класс ServiceBase содержал следующее:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private void ExecuteService()
{
for (;;)
{
if (_stop.WaitOne(1000))
{
new TcpServer().StartTcpServer();
return;
}
}
}
Правильная реализация заключалась в том, чтобы удалить цикл for
, который был повторно инициализирован слушателем. Вот окончательный код:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private static void ExecuteService()
{
new TcpServer().StartTcpServer();
}
Start
- это то, что вызываетSocketException
. Так как это не в вашей попытке, ваш улов и, наконец, не пострадали. Переместите свойStart
в свою попытку и проверьте свойство ErrorCode вашегоSocketException
в вашем операторе catch. Это даст вам лучшее представление о том, что не так. Затем проверьте код ошибки в этом списке, чтобы увидеть, в чем именно заключается проблема.