4

使用线程时,使用'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) 之间'


如果我们在'timer event'中检查后将处理的数据分散在'thread'中,而不使用'invoke'或其他方法,会不会有问题?(我们听说在打印“线程”内处理的数据时,为了避免“跨线程”,使用额外的“定时器对象”分散“定时器事件”中的数据已经很频繁了,因为它既无益也无害)。

4

2 回答 2

5

只需使用一个BackgroundWorker实例并处理已经在正确线程中的ReportProgress和/或事件。RunWorkerCompleted

于 2012-01-16T07:14:31.810 回答
1

正如 Ben Voigt 建议的那样,aBackgroundWorker可能是您应该在这里使用的,除非您有充分的理由想要使用其他东西。

“有效”是一种比较模糊的比较手段。在您正在考虑的两个选项中,您正在寻找什么并不完全清楚。

BackgroundWorkers 简单易懂,并且避免使用计时器。

Invoke比计时器更有效,因为 bCheckState 变为 true 和更新文本之间的延迟会更短。它也将减少 CPU 密集度,因为您不会在设定的时间间隔内进行计时器轮询。

更有效的Timer是线程在调用更新文本时不必停止,但效率有点低,因为它会浪费 CPU 时间检查布尔值是否已更改,并且还可能存在在表单更改之前延迟最多计时器间隔长度。

作为另一种选择,BeginInvoke可用于在不使用计时器的情况下更新表单,并且线程不必等待调用完成。但是,如果它引发异常,您的线程可能不会发现,除非您还调用EndInvoke,这也将暂停线程的执行,直到调用完成。

它们都有其优点和缺点,一般来说,你不能真正称任何特定的一个更“有效”。

于 2012-01-17T00:10:32.183 回答