使用线程时,'invoke'用于避免'Cross Thread'(1)
但是,有时候“计时器对象”被用来避免“CrossThread”(2)
像这样(例如)
public partial class Form1 : Form
{
private bool bCheckState = false;
public Form1()
{
InitializeComponent();
}
//Button Click
private void btnWork_Click(object sender, EventArgs e)
{
Thread m_Thread = new Thread(new ThreadStart(Work));
m_Thread.Start();
}
private void Work()
{
bCheckState = true;
// not use invoke
}
private void timer_Tick(object sender, EventArgs e)
{
if (bCheckState)
{
//tbxDisplay is winform's textBox control - printing data
tbxDisplay.Text = bCheckState.ToString();
bCheckState = false;
}
}
}
哪个更有效? '在(1)和(2)'之间
如果我们在“计时器事件”中检查后在“线程”内分散处理的数据,而不使用“调用”或其他方法,是否会出现问题? (我们听说在打印'thread'中处理的数据时要避免'Cross-Thread',在'timer event'中散布带有附加'timer object'的数据经常被使用,因为它既不有益也无害。
答案 0 :(得分:5)
只需使用BackgroundWorker
实例并处理已在正确主题中的ReportProgress
和/或RunWorkerCompleted
个事件。
答案 1 :(得分:1)
正如Ben Voigt所说,BackgroundWorker
可能是你应该在这里使用的,除非你有充分的理由想要使用别的东西。
“有效”是一种相当模糊的比较手段。在你正在考虑的两个选项中,你所要找的并不完全清楚。
BackgroundWorker
简单易懂,避免使用计时器。
Invoke
比计时器更有效,因为bCheckState变为true和正在更新的文本之间的延迟会更少。它也会减少CPU占用,因为您不会在设定的时间间隔内进行定时器轮询。
Timer
更有效,因为线程在调用更新文本时不必停止,但它有点效率低,因为它会浪费CPU时间检查布尔值是否有更改,并且在表单更改之前还可能延迟到计时器间隔长度。
作为另一种选择,BeginInvoke
可用于在不使用计时器的情况下更新表单,并且线程不必等待调用完成。但是,如果它引发异常,你的线程可能无法找到,除非你也调用EndInvoke
,这也将停止执行该线程直到调用完成。
他们都有自己的优点和缺点,一般来说,你不能把任何一个特别的人称为“有效”。