首页 > 解决方案 > C# - 从另一个方法停止计时器

问题描述

我正在尝试用 C# 学习 OOP。目标框架:.net core 3.1。我有两节课。在第一个中,我初始化计时器:

public class Test
{
    Timer timer = new Timer();
    public void Begin()
    {
        timer.Elapsed += new ElapsedEventHandler(Action);
        timer.Interval = 1000;
        timer.Start();
    }
    public virtual void Action(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("Running");
    }

    public void Finish()
    {
        timer.Stop();
        timer.Dispose();
    }
}

在主类中,我有两种方法用于启动计时器和停止计时器

class Program
{
    static void Main(string[] args)
    {
        Start();

        ConsoleKeyInfo input;
        do
        {
            input = Console.ReadKey();
        } while (input.Key != ConsoleKey.Escape);

        Console.WriteLine("Stopping");
        Stop();
        Console.ReadLine();
    }

    static void Start()
    {
        Test a = new Test();
        a.Begin();
        Console.WriteLine("Started");
    }

    static void Stop()
    {
        Test a = new Test();
        a.Finish();
        Console.WriteLine("Stopped");
    }
}

为什么定时器在停止和处理后仍然运行?

标签: c#

解决方案


你很亲近!正如 Chamika 在评论中指出的那样,您正在与Test班级的两个不同实例进行交互。new关键字的意思是,new创建一个实例Test

要更正此问题,您可以创建 aglobal variable或将实例传递给您的Start()andStop()方法。

首先,我将展示global variable解决方案。


没有编辑你的Test课程,我修改了你的Program课程。我创建了一个global variable: myTimermyTimer设置为Test类的新实例。我还从您的Start()andStop()方法中删除了其他实例创建。因为他们在同一个班级,所以无论设置为还是Program,他们都可以与您互动!global variablepublicprivate

    class Program
    {
        // Global variable to use within the class. 
        //  - This maintains the correct/same instance of the Test() class 
        //  - to interact with, starting/stopping.
        public static Test myTimer = new Test();

        public static void Main(string[] args)
        {
            Start();

            ConsoleKeyInfo input;
            do
            {
                input = Console.ReadKey();
            } while (input.Key != ConsoleKey.Escape);

            Console.WriteLine("Stopping");
            Stop();
            Console.ReadLine();
        }

        static void Start()
        {
            // I removed the Test a = new Test() line as it creates 
            // - a 'new' instance of the Test() class

            // Set the instance to interact with to the global variable: myTimer
            myTimer.Begin();
            Console.WriteLine("Started");
        }

        static void Stop()
        {
            // I removed the Test a = new Test() line as it creates 
            // - a 'new' instance of the Test() class

            // Set the instance to interact with to the global variable: myTimer
            myTimer.Finish();
            Console.WriteLine("Stopped");
        }
   }

// Output:
//  Started
//  Running
//  Running
//  Running
//  ... 
//  Stopping
//  Stopped 

这是passing variable另一种思考方式的解决方案!

进行了大约相同数量的更改,只是以不同的方式进行。类Test仍然没有被触及或改变。

而不是创建 a global variable,将 the 添加arguments到您的,以便他们期望传递methods一个实例。Test在您的方法中创建实例Main,然后传递变量。

    class Program
    {
        public static void Main(string[] args)
        {
            // Create the instance of the 'Test' class. 
            // Since this is created in the 'Main' scope, passing it to 
            // Start() and Stop() will use this instance.
            Test myTimer = new Test();

            // Pass 'myTimer' to Start() to start timer
            Start(myTimer);

            ConsoleKeyInfo input;
            do
            {
                input = Console.ReadKey();
            } while (input.Key != ConsoleKey.Escape);

            Console.WriteLine("Stopping");
            // Pass 'myTimer' to Stop() to stop timer
            Stop(myTimer);
            Console.ReadLine();
        }

        static void Start(Test myTimer)
        {
            myTimer.Begin();
            Console.WriteLine("Started");
        }

        static void Stop(Test myTimer)
        {
            myTimer.Finish();
            Console.WriteLine("Stopped");
        }
  }

// Output:
//  Started
//  Running
//  Running
//  Running
//  ... 
//  Stopping
//  Stopped 

推荐阅读