概要:
在 Windows服务和控制台应用程序我正在调用一个公共库,其中包含定时器,定期触发大约需要30秒钟的操作.不过这样做很好

当服务停止或应用程序退出被调用并且计时器在ElapsedEventHandler中时,我需要服务停止/应用程序退出等待直到事件处理程序完成.

我已经通过在调用定时器停止方法时检查一个Boolean InEvent属性来实现这个功能.

虽然这是功能,但问题是:这是最好的办法吗?是否有更好的方法可以更好地达到这个目的?

另一个问题是我需要避免服务停止请求失败,并显示“服务无法响应停止请求”

这是我的实现

public sealed class TimedProcess : Idisposable
{
    static TimedProcess singletonInstance;
    bool InEvent;
    Timer processtimer;

    private TimedProcess()
    {
    }

    public static TimedProcess Instance
    {
        get
        {
            if (singletonInstance == null)
            {
                singletonInstance = new TimedProcess();
            }

            return singletonInstance;
        }
    }

    public void Start(double interval)
    {
        this.processtimer = new Timer();
        this.processtimer.AutoReset = false;
        this.processtimer.Interval = interval;
        this.processtimer.Elapsed += new ElapsedEventHandler(this.processtimer_Elapsed);
        this.processtimer.Enabled = true;
    }

    public void Stop()
    {
        if (processtimer != null)
        {
            while (InEvent)
            {
            }

            processtimer.Stop();
        }
    }

    void processtimer_Elapsed(object sender,ElapsedEventArgs e)
    {
        try
        {
            InEvent = true;
            // Do something here that takes ~30 seconds
        }
        catch
        {
        }
        finally
        {
            InEvent = false;
            processtimer.Enabled = true;
        }
    }

    public void dispose()
    {
        if (processtimer != null)
        {
            Stop();
            processtimer.dispose();
        }
    }
}

这就是在OnStart / console应用程序main中调用的方法:

TimedProcess.Instance.Start(1000);

这是在服务OnStop和应用程序main(挂起的按键)中如何调用:

TimedProcess.Instance.Stop();

解决方法

可能最简单和最可靠的方法是使用监视器.创建主程序和定时器回调可以访问的对象:
private object _timerLock = new object();

您的主程序在关闭之前尝试锁定:

// wait for timer process to stop
Monitor.Enter(_timerLock);
// do shutdown tasks here

你的定时器回调也锁定它:

void processtimer_Elapsed(object sender,ElapsedEventArgs e)
{
    if (!Monitor.TryEnter(_timerLock))
    {
        // something has the lock. Probably shutting down.
        return;
    }
    try
    {
        // Do something here that takes ~30 seconds
    }
    finally
    {
        Monitor.Exit(_timerLock);
    }
}

主程序一经获取就不应该释放锁.

如果您希望主程序在一段时间后继续关闭,无论是否获得锁定,请使用Monitor.TryEnter.例如,这将等待15秒.

bool gotLock = Monitor.TryEnter(_timerLock,TimeSpan.FromSeconds(15));

如果能够获得锁,则返回值为true.

顺便问一下,我强烈建议您使用System.Threading.Timer而不是System.Timers.Timer.后者阻止例外,最终可能会隐藏错误.如果您的Elapsed事件发生异常,它将永远不会被转义,这意味着您永远不会知道它.有关更多信息,请参阅我的blog post.

c# – 在应用程序/服务关闭/停止之前等待定时器已过事件完成的更多相关文章

  1. swift 定时器的使用

    参考:http://www.cnblogs.com/sxlfybb/p/3792611.htmlNSTimer有2个构造函数注意到,注释为未继承,所以两个构造不能用NSTimer有2个静态实例在swift中,找不到NSInvocation类,日了狗了还好有另一种使用静态函数的形式去实例化:

  2. Swift - 时间控制器NSTimer每隔一定时间执行某个函数

  3. Swift/OC计时器使用方法

    .invalidate();timer=nil;}

  4. swift3.0 Timer 定时器

    贡献者:赵大财博客:https://my.oschina.net/zhaodacaiGitHub:https://github.com/zhaodacai邮箱:zhaodacai@yeah.comQQ:327532817=============================

  5. 在Swift中使用NSTimer

    在这种情况下,timerFunc()从未被调用。您可以创建一个自动将自己添加到runloop并开始启动的计划定时器:或者,你可以保留你当前的代码,并添加定时器runloop当你准备好了:

  6. 使用Android中的加速度计准确检测移动

    我正在实施一个演示TIMER,具有振动(在特定条件下),当我按开始我的定时器开始运行..当我停止它使用停止按钮,它只是停止.现在我必须集成一个功能,当人员移动设备(在定时器运行时),它应该重置定时器.它的工作相当不错,但是加速度计的功能并不是绝对准确的.需要一个快速的跳动来重置定时器.给我一个很好的解决方案.这是我的代码}计时器活动解决方法我认为开发应用程序的下一个阶段是查看电子表格中生成的加速度

  7. 详解Nodejs的timers模块

    本篇文章主要介绍了Nodejs的timers模块,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. Angular.js中定时器循环的3种方法总结

    这篇文章主要给大家总结了angular.js中定时器循环的3种方法,分别是利用$interlval实现、$timeout的递归调用来实现以及$timeout借助arguments.callee来实现,每种方法都给出了详细的示例艾玛供大家学习参考,需要的朋友们下面跟着小编一起来学习学习吧。

  9. 浅析javascript 定时器

    这篇文章主要简单介绍了javascript 定时器的相关知识,包括 setTimeout()以及clearInterval() 的定义和用法,非常实用,推荐给大家

  10. JavaEE线程安全定时器模式任务

    这篇文章主要介绍了JavaEE线程安全定时器模式任务,定时器模式像是一个闹钟定时,在一定时间之后被唤醒并执行某个之前设定好的任务,感兴趣的小伙伴可以参考一下

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部