加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

.NET Windows服务需要使用STAThread

发布时间:2020-12-13 20:16:48 所属栏目:Windows 来源:网络整理
导读:我已经创建了一个 Windows服务,将调用一些COM组件,所以我标记了[STAThread]到主要功能.但是,当定时器触发时,它会报告MTA并且COM调用失败.如何解决这个问题? using System;using System.Diagnostics;using System.ServiceProcess;using System.Threading;usi
我已经创建了一个 Windows服务,将调用一些COM组件,所以我标记了[STAThread]到主要功能.但是,当定时器触发时,它会报告MTA并且COM调用失败.如何解决这个问题?
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;



namespace MyMonitorService
{
    public class MyMonitor : ServiceBase
    {
        #region Members
        private System.Timers.Timer timer = new System.Timers.Timer();
        #endregion

        #region Construction
        public MyMonitor ()
        {
            this.timer.Interval = 10000; // set for 10 seconds
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
        }
        #endregion

        private void timer_Elapsed (object sender,ElapsedEventArgs e)
        {
            EventLog.WriteEntry("MyMonitor",String.Format("Thread Model: {0}",Thread.CurrentThread.GetApartmentState().ToString()),EventLogEntryType.Information);
        }

        #region Service Start/Stop
        [STAThread]
        public static void Main ()
        {
            ServiceBase.Run(new MyMonitor());
        }

        protected override void OnStart (string[] args)
        {
            EventLog.WriteEntry("MyMonitor","My Monitor Service Started",EventLogEntryType.Information);
            this.timer.Enabled = true;
        }

        protected override void OnStop ()
        {
            EventLog.WriteEntry("MyMonitor","My Monitor Service Stopped",EventLogEntryType.Information);
            this.timer.Enabled = false;
        }
        #endregion
    }
}
服务由使用MTA线程运行的Windows服务托管系统运行.你不能控制这个.你必须创建一个新的 Thread和 set its ApartmentState to 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线程(可能开始的两倍的核心数),它监视工作项的线程安全队列.定时器tick事件将负责在需要完成的工作中加载该队列.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读