在timer_tick事件中提出个人事件 [英] Raise a personal event in timer_tick event

查看:104
本文介绍了在timer_tick事件中提出个人事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个包含计时器的小类CountDown。



类非常简单:接收时间目标,并使用计时器启动CountDown。 br $>


达到目标时,我的个人活动开火





I have create a small class CountDown , that contains a timer.

Class is very simple : receive time target, and start a CountDown with a timer.

When target is reached, my personal event fire


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CountDownWithEvent
{
    public delegate void countDownFinishEventHandler(Object sender, EventArgs e);
    class CountDown
    {
        private DateTime _target;
        private System.Windows.Forms.Timer _timer;
        System.TimeSpan _timeMissing;


        public event countDownFinishEventHandler CountDownFinish;

        public CountDown(DateTime targetTime)
        {
            this._target = targetTime;
            this._timer = new System.Windows.Forms.Timer();
            this._timeMissing = new TimeSpan();
        }

        public DateTime TargetTime
        {
            get;
        }

        public TimeSpan timeMissing
        {
            get;
        }

        public void CountDownStart()
        {
            _timer.Interval = 1000;
            _timer.Tick += new EventHandler(timer_tick);
            _timer.Start();
        }

        protected virtual void timer_tick(Object sender, EventArgs e)
        {
            //if (_timer.Tick != null)
            //{
            //}
            System.DateTime now = System.DateTime.Now;
            _timeMissing = _target.Subtract(now);
            if (!(timeMissing.TotalSeconds > 0))
            {
                _timer.Stop();
                if(CountDownFinish != null)
                {
                    EventArgs b = new EventArgs();
                    CountDownFinish(this, b);
                }
            }
        }


    }
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CountDownWithEvent
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CountDown CountDown = new CountDown(new DateTime(2016, 05, 27, 14, 48, 00));
            CountDown.CountDownFinish += new countDownFinishEventHandler(onCountDown);
            CountDown.CountDownStart();
        }

        private void onCountDown(Object sender, EventArgs e)
        {
            MessageBox.Show("time expired! ");
        }
    }
}







我使用EventArgs,而不是写一个派生类,因为我不需要任何特殊的事件信息(要理解,参数e)



现在我处于一种情况有点不寻常:






I use EventArgs, rather than write a derived class , because I don't need any special information of the event ( to understand, parameter e)

now I'm in a situation a bit unusual :

protected virtual void timer_tick(Object sender, EventArgs e)
    {
        //if (_timer.Tick != null)
        //{
        //}
        System.DateTime now = System.DateTime.Now;
        _timeMissing = _target.Subtract(now);
        if (!(timeMissing.TotalSeconds > 0))
        {
            _timer.Stop();
            if(CountDownFinish != null)
            {
                EventArgs b = new EventArgs();
                CountDownFinish(this, b);
            }
        }
    }





当我打电话给



When i call

CountdownFinish(this,e);

e

参数引用timer_tick它不是t一致传递EventArgs计时器所以我不知道如何表现???



实际上我已经实例化了

parameter refer an timer_tick It isn t consistent pass EventArgs timer so I don t know how to behave ???

In fact I have instantiated

new EventArgs b







EventArgs b = new EventArgs();
CountDownFinish(this, b);





但我不知道这是不是正确的道路



现在我的另一个问题是:



我想在标签上看到留给目标的时间。并将其刷新到任何timer_tick。而我想保持程序图形的计时器逻辑分离..我怎么能这样做?



非常感谢您的理解和帮助! (抱歉英语不好,不是我的语言:))



我尝试过的事情:



我的努力和我的测试就在上面..谢谢



but I don t know if this is the right path

Now im another problem :

I want to see in label the time left to goal. And refresh it to any timer_tick. whereas I want to keep separated the timer logic of the program graphic.. how I can do it?

Many thanks in advance for the understanding and the help! (sorry for bad english, isn t my language :) )

What I have tried:

my efforts and my tests are just above .. thanks

推荐答案

这里的主要错误是使用
System.Windows.Forms<br />

。你不能指望这种计时器有什么好处。据我所见,您需要或多或少的周期性行为,以查看标签如何显示倒计时时间。有了这个计时器,甚至不要梦想它,即使有时你会有这种行为的印象。它的准确性非常差。它只有一个好处:事件处理程序将在同一个UI线程中调用。为这个可疑的好处付出不好的时机将是一个错误的选择。



相反,你可以使用 System.Timers.Timer

定时器类(System.Timers) [ ^ ]。



还有另一个选项,它将是最可靠的选项:单独使用倒计时的线程;使用延迟内部人员执行循环,稍微小于预期的时间段。它不会给您完全定期执行,但您可以在显示屏幕上的时间之前从系统中查询实时值。获得时间的最准确方法是 System.Diagnostics.Stopwatch

秒表类(System.Diagnostics) [ ^ ]。



顺便说一句,你可以在所有情况下进行这次修正。为了使其更准确,您可以在UI线程中修改屏幕上的文本之前立即执行此操作。现在让我们谈谈使用这个线程。



我建议的两种方法都需要从不同的线程通知UI线程。这是您必须解决的剩余问题。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



您将在我过去的答案中找到有关其工作原理和代码示例的详细说明:

Control.Invoke()与Control.BeginInvoke()

使用Treeview扫描仪和MD5的问题



另请参阅有关线程的更多参考资料:

主要的.NET事件线程

如何让keydown事件在不同的线程上运行i n vb.net

在启用禁用+多线程后控制事件未触发



-SA

. You cannot expect anything good from this kind of a timer. As far as I can see, you need more or less periodic behavior, to see how the label shows count down time. With this timer, don't even dream about it, even if sometimes you got an impression of such behavior. Its accuracy is prohibitively poor. It has only one benefit: the event handler will be called in the same UI thread. Paying by poor timing for this questionable benefit would be a wrong choice.

Instead, you can use System.Timers.Timer:
Timer Class (System.Timers)[^].

There is another option, which will be the most reliable one: use a separate thread for count down; execute a loop with the delay insider, somewhat smaller then the expected period. It won't give you exactly periodic execution, but you can inquire a real time value from the system right before showing the time on screen. Most accurate way to get the time is System.Diagnostics.Stopwatch:
Stopwatch Class (System.Diagnostics)[^].

By the way, you can do this time correction in all cases. To make it more accurate, you can do it immediately before modifying the on-screen text, right in the UI thread. Let's talk about working with this thread now.

Both methods I suggest will require notification of the UI thread from a different thread. This is the remaining problem you have to solve. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke(),
Problem with Treeview Scanner And MD5.

See also more references on threading:
.NET event on main thread,
How to get a keydown event to operate on a different thread in vb.net,
Control events not firing after enable disable + multithreading.

—SA


这篇关于在timer_tick事件中提出个人事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆