使用 System.Timers.Timer 打开新表单有多糟糕?

发布于 2024-09-10 23:03:26 字数 1688 浏览 3 评论 0原文

我的 c# WinForm 应用程序使用 System.Timers.Timer 的 Elapsed 事件打开一个新表单。有人向我指出(在我之前发布的关于不同主题的问题中)这是一个坏主意;有人建议我使用 System.Windows.Forms.Timer。

我已根据此建议更改了代码,并且我的应用程序似乎可以正常工作;然而,我的 WinForms 学习曲线仍然相当低,我希望得到有关我是否正确更改代码的反馈。 (我很担心,因为旧的方式——糟糕的方式——似乎也有效。)

我有两种形式:frmTimer 和 frmUser。每个表单都驻留在 WinForms 解决方案中的单独项目中。 FrmTimer 使用命名空间“svchostx”并从 svchostx.exe 运行。 FrmUser 使用命名空间“XXXUser”并从 XXXUser.exe 运行(其中 XXX 是应用程序的名称)。

在这种情况下使用 System.Timers.Timer 是否不好?如果是,那么我是否做出了正确的更改?

在 frmTimer 中,此代码:

this.tmTimer= new System.Timers.Timer();
((System.ComponentModel.ISupportInitialize)(this.tmTimer)).BeginInit();
// 
// tmTimer
//
this.tmTimer.Interval = 20000;
this.tmTimer.SynchronizingObject = this;
this.tmTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.tmTimer_Elapsed);
private System.Timers.Timer tmTimer;

private void tmTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {

替换为此代码:

this.timer1 = new System.Windows.Forms.Timer(this.components);
// 
// timer1
// 
this.timer1.Interval = 20000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
private System.Windows.Forms.Timer timer1;

private void timer1_Tick(object sender, System.EventArgs e) {

在旧代码和新代码中,计时器事件检查是否满足某些条件,当满足条件时,打开 frmUser。 FrmUser 显示用户回答的测验屏幕(包含数学或拼写问题)。 FrmTimer 永远不会被看到,仅包含确定何时打开 frmUser 的逻辑。

此外,Visual Studio 的 IntelliSense 对于 System.Windows.Forms.Timer 是这样说的:“此计时器针对在 Windows 窗体应用程序中使用进行了优化,并且必须在窗口中使用。”这句话的最后部分让我感到困惑,因为 frmTimer 并没有真正的窗口(表单从未见过)。我不确定“必须在窗口中使用”是什么意思——是的,我的学习曲线相当低。

如有任何建议或帮助,我们将不胜感激。

My c# WinForm application uses the Elapsed event of a System.Timers.Timer to open a new form. It was pointed out to me (in an earlier question I posted on a different topic) that this was a bad idea; it was suggested I use System.Windows.Forms.Timer.

I've changed my code in response to this suggestion and my application appears to work; however, I'm still rather low on the WinForms learning curve and I'd enjoy feedback on whether or not I've correctly changed my code. (I'm concerned because the old way--the bad way--also appeared to work.)

I have two forms: frmTimer and frmUser. Each form resides in a separate project in the WinForms solution. FrmTimer uses the namespace 'svchostx' and runs from svchostx.exe. FrmUser uses the namespace 'XXXUser' and runs from XXXUser.exe (where XXX is the application's name).

Is it bad to use System.Timers.Timer in this context and, if it is, then have I made the correct changes?

In frmTimer this code:

this.tmTimer= new System.Timers.Timer();
((System.ComponentModel.ISupportInitialize)(this.tmTimer)).BeginInit();
// 
// tmTimer
//
this.tmTimer.Interval = 20000;
this.tmTimer.SynchronizingObject = this;
this.tmTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.tmTimer_Elapsed);
private System.Timers.Timer tmTimer;

private void tmTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {

Was replaced with this code:

this.timer1 = new System.Windows.Forms.Timer(this.components);
// 
// timer1
// 
this.timer1.Interval = 20000;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
private System.Windows.Forms.Timer timer1;

private void timer1_Tick(object sender, System.EventArgs e) {

In both the old code and the new code, the timer event checks to see if certain conditions are meet, and when they're meet, then frmUser is opened. FrmUser shows a quiz screen (with math or spelling questions) that the user answers. FrmTimer is never seen and contains only logic to determine when frmUser is opened.

Also, Visual Studio's IntelliSense says this about System.Windows.Forms.Timer: "This timer is optimized for use in Windows Forms applications and must be used in a window." The last part of that sentence confuses me because frmTimer doesn't really have a window (the form is never seen). I'm not sure what is meant by 'must be used in a window'--yes, I am pretty low on the learning curve.

Any advice or help here is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌梦深 2024-09-17 23:03:26

您使用 System.Timers.Timer 的方式是正确的。使此计时器在 UI 场景中工作的关键是 SynchronizingObject 属性。当设置为 null 时,此计时器会在 ThreadPool 线程上引发 Elapsed 事件。当设置为 ISynchronizeInvoke 对象的实例时,它会在托管该对象的线程上引发事件。如果该 ISynchronizeInvoke 实例只不过是一个控件或表单,那么托管线程就是在主 UI 线程上创建该控件或表单的线程。

System.Windows.Forms.Timer 只能在 UI 场景中使用,因为它创建一个窗口句柄。您实际上并没有看到该窗口被创建,但它确实存在。当然,这个计时器总是在 UI 线程上引发其 Tick 事件。

The way you are using the System.Timers.Timer is correct. The key to making this timer work in UI scenarios is the SynchronizingObject property. When set to null this timer raises the Elapsed event on a ThreadPool thread. When set to an instance of an ISynchronizeInvoke object it raises the event on the thread hosting that object. If that ISynchronizeInvoke instance is none other than a control or form then the hosting thread is the thread that the control or form was created on...the main UI thread.

The System.Windows.Forms.Timer can only be used in UI scenarios because it creates a window handle. You do not actually see this window get created, but it is there. And of course this timer always raises its Tick event on the UI thread.

狼亦尘 2024-09-17 23:03:26

使用 System.Windows.Forms.Timer 与 WinForms 交互。
System.Timers.Timer 是为其他目的而构建的,例如后台操作和服务,并且它不与 UI 线程同步。

另请查看此处

Use System.Windows.Forms.Timer for interaction with WinForms.
System.Timers.Timer is built for other purposes, like background operations and services, and its not synchronized with UI Threads.

Have also a look here.

月牙弯弯 2024-09-17 23:03:26

此处了解 .net 中提供的三种类型的计时器。使用 System.Windows.Forms.Timer 进行 UI 编程确实没有什么问题。

Read about the three types of timers available in .net from here. There is really nothing wrong with using the System.Windows.Forms.Timer for UI programming.

睫毛溺水了 2024-09-17 23:03:26

如果在同一个线程中创建两个窗口,则任何使一个窗口的 UI 线程停止的操作都会使两个窗口停止。另一方面,一个窗口中的控件可以自由地操纵另一个窗口,而不需要任何显式同步。如果您使用 forms.Timer,则只能在 UI 空闲时创建新窗口;除非您尽力做到这一点,否则您的新表单将使用与计时器相同的线程。如果您使用其他类型的计时器,即使所有其他 UI 线程都忙,您的新表单也可以出现;新表单不会与其他表单共享线程。请注意,由于表单的线程在表单关闭之前不会终止,因此(从计时器事件)创建一个新线程可能比占用线程池线程更好。

If two windows are created in the same thread, then anything which stalls the UI thread for one will stall it for both. On the other hand, controls from one window can freely manipulate the other window without requiring any explicit synchronization. If you use a forms.Timer, your new window can only be created when the UI is idle; unless you endeavor to make it otherwise, your new form will use the same thread as the one with the timer. If you use another type of timer, your new form can appear even when all other UI threads are busy; the new form will not share a thread with other forms. Note that since the form's thread won't die until the form is closed, it may be better to create a new thread (from the timer event) than hog a thread-pool thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文