【问题标题】:Is it possible to stop a Timer (System.Timers.Timer) from inside the OnTimedEvent Method是否可以从 OnTimedEvent 方法内部停止计时器(System.Timers.Timer)
【发布时间】:2020-10-16 07:52:45
【问题描述】:

我正在尝试制作一个倒计时功能,当计时器到达 0 时它会停止。到目前为止发生的事情是,当计时器到达 0 时(并且我没有按下任何键),它会不断向我发送默认消息在我点击一个按钮之前它不会停止。

我想在OnTimedEvent 中插入一些代码,这将停止计时器(一旦它达到零,显示消息并停止向我发送垃圾邮件)。我尝试了aTimer.Stop aTimer.Enabled = false; 等的多种变体。

我收到一个错误

当前上下文中不存在名称“aTimer”。

代码:

使用系统;
使用 System.Timers;

命名空间 MyProject
{
    课堂节目
    {
        静态无效主要(字符串 [] 参数)
        {
            Console.WriteLine("主线程仍在运行");
            Console.WriteLine("按 X 拯救世界。");
            Console.WriteLine("你有 10 秒!");

            System.Timers.Timer aTimer = new System.Timers.Timer(1000);
            aTimer.Elapsed += OnTimedEvent;
            aTimer.Enabled = true;


            ConsoleKeyInfo 输入 = Console.ReadKey(true);

            开关(输入.KeyChar)
            {
                默认:
                    Console.WriteLine("废话");
                    aTimer.Enabled = 假;
                    休息;
            }

            Console.ReadKey();
        }

        私有静态 int _countDown = 10; // 秒
        私有静态 bool dMade = false;

        静态无效 OnTimedEvent(对象源,ElapsedEventArgs e)
        {
            如果(dMade == false)
            {
                如果 (_countDown-- 
    

【问题讨论】:

    标签: c# timer


    【解决方案1】:

    我收到一个错误当前不存在名称“aTimer” 上下文。

    这是因为 aTimer 不在 OnTimedEvent 方法的范围内。 aTimer 的范围在 Main 方法中,因为这是声明它的地方。 如果将 aTimer 移动到 Program 类中的静态字段而不是局部变量,它将在其中的所有方法的范围内:

    课程 { 静态 System.Timers.Timer aTimer; 静态无效主要(字符串 [] 参数) { Console.WriteLine("主线程仍在运行"); Console.WriteLine("按 X 拯救世界。"); Console.WriteLine("你有 10 秒!"); aTimer = new System.Timers.Timer(1000); aTimer.Elapsed += OnTimedEvent; aTimer.Enabled = true; ...

    然后你可以在你的 OnTimedEvent 方法中引用 aTimer。

    static void OnTimedEvent(object source, ElapsedEventArgs e)
            {
               aTimer.Enabled = 假;
    ...
    
    

    变量作用域取决于它的声明位置,因此如果它在类的主体中声明,则所有方法都可以访问它(如果它是静态的或方法不是静态的)。如果在方法的范围内声明了一个变量,则它仅对该方法可见(从声明它的那一点到该方法的右大括号 '}')。

    【讨论】:

    • 谢谢!这正是我“正在寻找的”
    • 没问题@DrDoom。下面的 Broots 回答也有效,但请注意,它不能防止错误的类型转换。
    • 我已经按照建议添加了代码,它确实停止了计时器。但现在我得到一个错误或aTimer.Enabled = false; -> Exception User-Unhandled ... System.NullRefernceException: 'Object reference not set to an instance of an object.'.
    • @DrDoom 您是否更改了实例化行以使用字段而不是局部变量声明:aTimer = new System.Timers.Timer(1000);
    • 没问题。然后,您在两个范围内有两个变量,都称为 aTimer。仅供参考,如果您想访问在类主体中声明的 aTimer,则必须执行“this.aTimer”。 :)
    【解决方案2】:

    OnTimedEvent 中,object source 是您的计时器。您可以使用以下行停止它:

    ((System.Timers.Timer) source).Enabled = false;
    

    【讨论】:

    • 谢谢你的回答,但你能详细说明一下吗? IE。显示应该插入的确切位置(显示更多定位代码)
    • @DrDoom - 你可以在任何你想在OnTimedEvent事件中停止你的计时器的地方使用这条线。对我来说,从你的代码中不清楚你想在那里的哪个位置停止它。 sourceOnTimedEvent 内的任何位置范围内,所以它的去向完全取决于您。
    • 哦。所以我不需要将它附加到任何东西上。那它就是一个独立的。谢谢你。我不知道为什么这会起作用。您能否直接访问相应的 Microsoft 页面,以便我阅读一下为什么/如何工作。
    • @DrDoom 之所以有效,是因为它是事件所属对象的标准 source 参数。例如,这与您想在 TextChanged 事件中访问 TextBox 相同。不幸的是,Timer.Elapsed 的文档并没有说明这一点......
    猜你喜欢
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2011-01-03
    • 1970-01-01
    相关资源
    最近更新 更多