c# - MyThread 和定时器控件的问题

标签 c# multithreading timer

我有一个方法,在第二个线程中被调用:

    public byte[] ReadAllBytesFromStream(Stream input)
    {
        clock.Start();

        using (...)
        {
            while (some conditions) //here we read all bytes from a stream (FTP)
            {
                ...
 (int-->)       ByteCount = aValue;
                ...
             }
            return .... ;
        }
    }

    private void clock_Tick(object sender, EventArgs e)
    {
        //show how many bytes we have read in each second
        this.label6.Text = ByteCount.ToString() + " B/s"; 
    }

问题是,时钟已启用,但它没有滴答作响。为什么?

更新:

正确添加了Tick事件,Interval属性设置为1000。

我将计时器控件放在设计 View 中的窗体上。

最佳答案

问题是您在第二个线程上启用了计时器,而该线程没有消息泵。

Windows 窗体计时器基于 SetTimer。启用计时器后,它会创建一个隐藏窗口并将该窗口的句柄发送到 SetTimer API,系统又会在每次计时器间隔结束时向该窗口发送一条 WM_TIMER 消息。然后隐藏窗口处理该消息并引发 Tick 事件。

在您的情况下,计时器是在第二个线程上创建的,但它没有消息泵,因此 WM_TIMER 消息永远不会到达您的窗口。您要做的是在 UI 线程上启用计时器,以便在发送 WM_TIMER 消息时在具有消息泵的 UI 线程中对其进行处理。假设您的过程在您的表单类中,您可以使用对表单的 this 引用来编码调用以启用计时器(如果它不在表单类中,您需要引用形式)像这样:

public byte[] ReadAllBytesFromStream(Stream input)
{
    if(this.InvokeRequired)
    {
        this.Invoke(new MethodInvoker(clock.Start));
    }
    else
    {
        clock.Start();
    }

    using (...)
    {
        while (some conditions) //here we read all bytes from a stream (FTP)
        {
            ...
 (int-->)   ByteCount = aValue;
            ...
         }
        return .... ;
    }
}

private void clock_Tick(object sender, EventArgs e)
{
    this.label6.Text = ByteCount.ToString() + " B/s"; //show how many bytes we have read in each second
}

关于c# - MyThread 和定时器控件的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1540281/

相关文章:

c# - 检查数据表中的现有值

c# - (C#) 如何在不加载或重写整个文件的情况下修改现有 XML 文件中的属性值?

android - 如何等到线程完成

c# - Parallel.ForEach 停止为最后几个项目并行

c# - 如何从 IGrouping 中获取值?

c++ - 在 C++/C 中在后台运行周期性循环

java - 类型不匹配错误 : Cannot convert from Player to Thread

javascript - Rails 4 - 计时器 (jQuery.Countdown)

java - 乒乓球游戏 - 为球动画添加计时器

c# - WPF 进度条在几条之后停止