#c# #windows-services
#c# #windows-services
Вопрос:
Итак, некоторое время назад я создал службу Windows, которая считывает последовательный порт и в зависимости от возвращаемого значения изменяет системный объем. Проблема в том, что когда я запускаю службу, она зависает в режиме запуска, но все еще делает то, что должна делать. но она не будет работать, если вы настроили ее на автоматический запуск при запуске. Я впервые создаю службу Windows, поэтому с ней может возникнуть много проблем.
вот запущенный код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using AudioSwitcher.AudioApi.CoreAudio;
using System.IO.Ports;
using System.Threading;
namespace audio_controller_WS
{
public partial class AudioContorllerWS : ServiceBase
{
static bool _continue;
static SerialPort _serialPort;
public AudioContorllerWS()
{
InitializeComponent();
}
public static void Read()
{
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
while (_continue)
{
try
{
String message = _serialPort.ReadLine();
int convert = int.Parse(message);
defaultPlaybackDevice.Volume = convert;
}
catch (Exception)
{ }
}
}
protected override void OnStart(string[] args)
{
// string message;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
Thread readThread = new Thread(Read);
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort();
// Allow the user to set the appropriate properties.
_serialPort.PortName = "COM10";
_serialPort.BaudRate = 9600;
_serialPort.DataBits = 8;
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_continue = true;
readThread.Start();
readThread.Join();
_serialPort.Close();
}
protected override void OnContinue()
{
}
protected override void OnStop()
{
}
}
}
Я знаю, что мой код не должен запускаться при запуске, но иначе я не работаю.
Комментарии:
1. Показывает ли она какое-либо сообщение при запуске службы?
2. Да, там написано «ошибка: 1053: служба неправильно ответила на команду запуска», что-то в этом роде, но это потому, что весь мой код находится в части «при запуске». но это своего рода проблема, если бы я вставил все в continue, у нее не было бы никаких ошибок, но она просто не делала бы ничего, что должна была. Она работает в фоновом режиме, но когда я отправляю сигнал, она ничего не делает.
3. Где вы устанавливаете _continue в false для выхода из цикла чтения? Кроме того, вам, вероятно, не следует присоединяться к потоку чтения при запуске. Служба остается в начальном состоянии до завершения работы этого метода. Служба продолжит работу после того, как метод будет создан, так что вы можете позволить потоку чтения выполняться в фоновом режиме.
4. Попробуйте обернуть код в метод onstart в новой задаче и сообщите мне о результатах.
Ответ №1:
Вам нужно разрешить методу OnStart завершить работу. Попробуйте это:
public partial class AudioContorllerWS : ServiceBase
{
static bool _continue;
static SerialPort _serialPort;
static Thread readThread;
public AudioContorllerWS()
{
InitializeComponent();
}
public static void Read()
{
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
while (_continue)
{
try
{
String message = _serialPort.ReadLine();
int convert = int.Parse(message);
defaultPlaybackDevice.Volume = convert;
}
catch (Exception)
{ }
}
}
protected override void OnStart(string[] args)
{
// string message;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
readThread = new Thread(Read);
// Create a new SerialPort object with default settings.
_serialPort = new SerialPort();
// Allow the user to set the appropriate properties.
_serialPort.PortName = "COM10";
_serialPort.BaudRate = 9600;
_serialPort.DataBits = 8;
// Set the read/write timeouts
_serialPort.ReadTimeout = 500;
_serialPort.WriteTimeout = 500;
_serialPort.Open();
_continue = true;
readThread.Start();
// don't join
}
protected override void OnContinue()
{
}
protected override void OnStop()
{
_continue = false;
readThread.Join(timeout);
_serialPort.Close();
// abort it if it hasn't exited
}
}
Комментарии:
1. Спасибо, что это сработало, единственное, что мне пришлось изменить, это переместить _serialport.close() также в onStop.