System.Windows.Forms.Timer没有发射 [英] System.Windows.Forms.Timer not firing

查看:198
本文介绍了System.Windows.Forms.Timer没有发射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 System.Windows.Forms.Timer 来确保我创建一个Excel插件的UI线程上的事件触发。我构建了定时器如下:

I want to use a System.Windows.Forms.Timer to ensure that an event fires on the UI thread of an excel addin I'm creating. I construct the timer as follows:

private System.Windows.Forms.Timer _timer;

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    Debug.WriteLine("ThisAddIn_Startup:" + Thread.CurrentThread.ManagedThreadId);

    _timer = new System.Windows.Forms.Timer();
    _timer.Tick += new EventHandler(TimerEventHandler);
    _timer.Interval = 500;            
}



计时器由从我使用的是库COM事件触发:

The timer is fired by a COM event from a library I am using:

private void OnEvent()
{
    _timer.Start();
}



然后我想到了 _timer 来调用下面的方法时,它蜱:

I then expect the _timer to call the following method when it ticks:

public void TimerEventHandler(object sender, EventArgs args)
{
    _timer.Stop();
    Debug.WriteLine("Tick: " + Thread.CurrentThread.ManagedThreadId);                  
}



据我了解,当我创建的加载项线程定时器,即使它是从另一个线程(在这种情况下,COM事件)开始,应该触发线程创建它上,即插件线程。但是,这不会发生。

As I understand, when I create the timer in the Addin thread, even though it is started from another thread (COM event in this case), it should fire on the thread that it was created on, i.e. the addin thread. However, this doesn't happen.

我已经实现这个确切机制的 RTDServer 我过去写的(肯尼克尔所概述),它的工作原理。预期,但在 _timer 在这种情况下从来没有蜱

I have implemented this exact mechanism in an RTDServer I wrote in the past (as outlined by Kenny Kerr) and it works as expected but the _timer in this scenario never ticks.

我也看过的other SO文章这一点相同的行为,并不能弄清楚什么是对我的插件设置不同

I have also read other SO articles that point to the same behavior and can't figure out what is different about my addin setup?

编辑:
中的的OnEvent()方法被解雇了。

The OnEvent() method is fired.

推荐答案

我最初打算张贴此为发表评论,但它会变得太长。

I initially meant to post this as comment, but it turned to be too long.

首先,你的线程结构有点混乱对我来说,你描述的方式。把的Debug.WriteLine(一个OnEvent:+ Thread.CurrentThread.ManagedThreadId)的OnEvent ,让我们知道所有的线程你从你的调试输出见标识

Firstly, your thread structure is a bit confusing to me, the way you described it. Put Debug.WriteLine("OnEvent:" + Thread.CurrentThread.ManagedThreadId) inside OnEvent and let us know all thread IDs you see from your debug output.

这表示,规则是:


  • 您应该创建的WinForms定时上的 STA线程和线程应该配置为STA开始之前。

  • You should create WinForms' Timer object on an STA thread, and the thread should be configured as STA before it starts.

这线程可能会或可能不会是主UI线程(在其中创建您的主要形式),但它仍然应该执行一个消息循环(与<一个HREF =http://msdn.microsoft.com/en-us/library/system.windows.forms.application.run.aspx相对=nofollow> Application.Run )计时器事件火。有消息抽(例子的其他方式),但一般不从.NET代码控制这一点。

This thread may or may not be the main UI thread (where your main form was created), but it still should execute a message loop (with Application.Run) for timer events to fire. There are other ways of pumping messages (example), but generally you do not control this from .NET code.

您应该处理由WinForms的采购事件定时器在同一线程上创建它。然后,您可以前进这些事件,如果你想(使用的 SynchronizationContext的 发送发表),但我想不出任何原因的复杂性。

You should handle the events sourced by WinForms' Timer on the same thread it was created. You can then 'forward' these events to another thread context if you like (using SynchronizationContext Send or Post) but I can't think of any reasons for such complexity.

由@Maarten其实答案建议这样做,在我看来,以正确的方式。

The answer by @Maarten actually suggests the right way of doing it, in my opinion.

这篇关于System.Windows.Forms.Timer没有发射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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