.NET Windows服务需要使用STAThread

前端之家收集整理的这篇文章主要介绍了.NET Windows服务需要使用STAThread前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经创建了一个 Windows服务,将调用一些COM组件,所以我标记了[STAThread]到主要功能.但是,当定时器触发时,它会报告MTA并且COM调用失败.如何解决这个问题?
  1. using System;
  2. using System.Diagnostics;
  3. using System.ServiceProcess;
  4. using System.Threading;
  5. using System.Timers;
  6.  
  7.  
  8.  
  9. namespace MyMonitorService
  10. {
  11. public class MyMonitor : ServiceBase
  12. {
  13. #region Members
  14. private System.Timers.Timer timer = new System.Timers.Timer();
  15. #endregion
  16.  
  17. #region Construction
  18. public MyMonitor ()
  19. {
  20. this.timer.Interval = 10000; // set for 10 seconds
  21. this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
  22. }
  23. #endregion
  24.  
  25. private void timer_Elapsed (object sender,ElapsedEventArgs e)
  26. {
  27. EventLog.WriteEntry("MyMonitor",String.Format("Thread Model: {0}",Thread.CurrentThread.GetApartmentState().ToString()),EventLogEntryType.Information);
  28. }
  29.  
  30. #region Service Start/Stop
  31. [STAThread]
  32. public static void Main ()
  33. {
  34. ServiceBase.Run(new MyMonitor());
  35. }
  36.  
  37. protected override void OnStart (string[] args)
  38. {
  39. EventLog.WriteEntry("MyMonitor","My Monitor Service Started",EventLogEntryType.Information);
  40. this.timer.Enabled = true;
  41. }
  42.  
  43. protected override void OnStop ()
  44. {
  45. EventLog.WriteEntry("MyMonitor","My Monitor Service Stopped",EventLogEntryType.Information);
  46. this.timer.Enabled = false;
  47. }
  48. #endregion
  49. }
  50. }
服务由使用MTA线程运行的Windows服务托管系统运行.你不能控制这个.你必须创建一个新的 Threadset its ApartmentState to STA,并在这个线程上做你的工作.

这是一个扩展ServiceBase的类:

  1. public partial class Service1 : ServiceBase
  2. {
  3. private System.Timers.Timer timer;
  4.  
  5. public Service1()
  6. {
  7. InitializeComponent();
  8. timer = new System.Timers.Timer();
  9. this.timer.Interval = 10000; // set for 10 seconds
  10. this.timer.Elapsed += new System.Timers.ElapsedEventHandler(Tick);
  11. }
  12.  
  13. protected override void OnStart(string[] args)
  14. {
  15. timer.Start();
  16. }
  17.  
  18. private void Tick(object sender,ElapsedEventArgs e)
  19. {
  20. // create a thread,give it the worker,let it go
  21. // is collected when done (not IDisposable)
  22. var thread = new Thread(WorkerMethod);
  23. thread.SetApartmentState(ApartmentState.STA);
  24. thread.Start();
  25. OnStop(); // kill the timer
  26. }
  27.  
  28. private void WorkerMethod(object state)
  29. {
  30. // do your work here in an STA thread
  31. }
  32.  
  33. protected override void OnStop()
  34. {
  35. timer.Stop();
  36. timer.Dispose();
  37. }
  38. }

注意这个代码实际上并不停止服务,它会停止定时器.在多线程上可能还有很多工作要做.例如,如果您的工作包括从大型数据库运行多个查询,则可能会导致崩溃,因为您同时运行的线程太多.

在这样的情况下,我将创建一组STA线程(可能开始的两倍的核心数),它监视工作项的线程安全队列.定时器tick事件将负责在需要完成的工作中加载该队列.

这一切都取决于你每十秒钟实际做什么,无论是否在下一次定时器打勾时应该完成,在这种情况下应该做什么等等

猜你在找的Windows相关文章