我有一个方法,在第二个Thread中调用:
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。
我将Timer Control放在设计视图中的表单上。
答案 0 :(得分:4)
问题是您在第二个线程上启用了计时器,并且此线程没有消息泵。
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
}
答案 1 :(得分:3)
在启动计时器之前,您需要将其Tick
事件附加到您要处理事件的方法。在这种情况下,您可以在启动计时器之前执行此操作:
clock.Tick += this.clock_Tick;
答案 2 :(得分:1)
只有主线程才能更新UI。假设您的时钟已正确初始化(正如其他人指出的那样)并且正在从第二个线程调用“clock_Tick”,您需要像这样重写它:
private void clock_Tick(object sender, EventArgs e)
{
// InvokeRequired will be true on every thread EXCEPT the UI thread
if (label6.InvokeRequired)
{
// Issue an asynchoronous request to the UI thread to perform the update
label6.BeginInvoke(new MethodInvoker(this.clock_Tick), sender, e);
}
else
{
// Actually do the update
label6.Text = ByteCount.ToString() + " B/s";
}
}
这适用于WinForms .. WPF语法略有不同,但功能相同。
以下是关于整个事件的文章:http://weblogs.asp.net/justin_rogers/pages/126345.aspx
祝你好运!答案 3 :(得分:0)
您是否设置了时钟的Interval属性?
答案 4 :(得分:0)
这只是一个猜测,但请确保您的计时器控件的Tick事件正确绑定到您的clock_Tick方法。
答案 5 :(得分:0)
你可能有一个“System.timer”和一个“windows.form.timer”冲突,System.timer在一个单独的线程上运行,而form.timer在主线程中运行,以便在.designer.cs中运行将“计时器”更改为“System.windows.form.timer”它应该可以正常工作