c# - 从计时器线程调用 GUI 线程上的方法

标签 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());
        }
    }
}

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

编辑:

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

最佳答案

Which timer你正在用吗? System.Windows.Forms.Timer 自动触发 UI 线程上的事件。如果您使用其他的,则需要使用 Control.Invoke在 UI 线程上调用方法。

关于c# - 从计时器线程调用 GUI 线程上的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3959107/

相关文章:

c# - 检查测试结束时是否还有任何线程残留

c++ - winrt/c++ : await result from dispatched task

java - 平滑组件在修改或循环后自动刷新(ex : timer)

c# - 在 C# 中从已运行的任务中初始化新任务

c# - SQLite多进程访问

c# - 枚举的基类

c# - 为什么未使用的物理线程数在 .NET 应用程序中波动?

java - 如何在 java 中以周期性间隔执行操作?

java - 如何按设定的时间间隔生成随机数?

c# - LINQ-to-SQL Table<T>.Attach 有什么作用?