Службы запускаются системой размещения служб Windows, которая работает с использованием потоков MTA. Вы не можете контролировать это. Вы должны создать новую тему и , установить для ее ApartmentState значение STA и выполнить свою работу в этой теме.
Вот класс, расширяющий ServiceBase, который делает это:
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer;
public Service1()
{
InitializeComponent();
timer = new System.Timers.Timer();
this.timer.Interval = 10000; // set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(Tick);
}
protected override void OnStart(string[] args)
{
timer.Start();
}
private void Tick(object sender, ElapsedEventArgs e)
{
// create a thread, give it the worker, let it go
// is collected when done (not IDisposable)
var thread = new Thread(WorkerMethod);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
OnStop(); // kill the timer
}
private void WorkerMethod(object state)
{
// do your work here in an STA thread
}
protected override void OnStop()
{
timer.Stop();
timer.Dispose();
}
}
Обратите внимание, что этот код на самом деле не останавливает службу, он останавливает таймер. Там может быть много работы по-прежнему выполняется на нескольких потоках. Например, если ваша работа состояла в выполнении нескольких запросов для большой базы данных, вы можете в конечном итоге привести к сбою, поскольку у вас одновременно запущено слишком много потоков.
В такой ситуации я бы создал заданное количество потоков STA (возможно, в два раза больше ядер, с которых нужно начинать), которые отслеживают потокобезопасную очередь для рабочих элементов. Событие отметки таймера будет отвечать за загрузку этой очереди необходимой работой.
Все зависит от того, что вы на самом деле делаете каждые десять секунд, должно ли оно быть выполнено в следующий раз, когда отметится таймер, что вам следует делать в этой ситуации и т. Д. И т. Д.