从定时器线程调用GUI线程上的方法

Tes*_*101 9 c# multithreading timer

在我的应用程序中,我使用计时器来检查RSS提要中的更新,如果找到新项目,我会弹出一个自定义对话框来通知用户.当我手动运行检查时,一切都很好,但是当自动检查在计时器Elapsed事件中运行时,不会显示自定义对话框.

首先是这是一个线程问题?(我假设这是因为手动和自动检查都使用相同的代码).

当我运行自动检查时,是否必须从Timers Elapsed事件处理程序调用运行检查的方法?

我的自定义对话框类中是否需要执行某些操作?

编辑:这是一个winforms应用程序.

以下是代码的示例.(请不要在此代码示例中指出语法错误,这只是一个简单的示例,而不是真正的代码).

public class MainForm : System.Windows.Forms.Form
{
    //This is the object that does most of the work.
    ObjectThatDoesWork MyObjectThatDoesWork = new ObjectThatDoesWork(); 
    MyObjectThatDoesWork.NewItemsFound += new NewItemsFoundEventHandler(Found_New_Items);

    private void Found_New_Items(object sender, System.EventArgs e)
    {
        //Display custom dialog to alert user.
    }

    //Method that doesn't really exist in my class, 
    // but shows that the main form can call Update for a manual check.
    private void Button_Click(object sender, System.EventArgs e)
    {
        MyObjectThatDoesWork.Update();
    }

    //The rest of MainForm with boring main form stuff
}


public class ObjectThatDoesWork
{
    System.Timers.Timer timer;

    public ObjectThatDoesWork()
    {
        timer = new System.Timers.Timer();
        timer.Interval = 600000;
        timer.AutoReset = true;
        timer.Elapsed += new new System.Timers.ElapsedEventHandler(TimeToWork);
        timer.Start();
    }

    private void TimeToWork(object sender, System.Timers.ElapsedEventArgs e)
    {
        Update();
    }

    public void Update()
    {
        //Check for updates and raise an event if new items are found.
        //The event is consumed by the main form.
        OnNewItemsFound(this);
    }

    public delgate void NewItemsFoundEventHandler(object sender, System.EventArgs e);
    public event NewItemsFoundEventHandler NewItemsFound;
    protected void OnNewItemsFound(object sender)
    {
        if(NewItemsFound != null)
        {
            NewItemsFound(sender, new System.EventArgs());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在阅读了一些评论和答案后,我认为我的问题是我使用的System.Timers.Timer不是System.Windows.Forms.Timer.

编辑:

更改为Forms.Timer之后,初始测试看起来很好(但是没有新项目存在,所以没有看到自定义对话框).我在调用update方法时添加了一些代码来将线程ID输出到文件中.使用Timers.Timer,线程ID不是GUI线程,但使用Forms.Timer,线程ID与GUI相同.

Gio*_*rgi 18

你在用哪个计时器?System.Windows.Forms.Timer自动在UI线程上触发事件.如果您正在使用其他的,则需要使用Control.Invoke在UI线程上调用该方法.