2012-01-16 129 views
4

当使用螺纹,“调用”被用来避免“跨线程”(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)”


难道是一个问题,如果我们在“定时器事件”检查之后散射“线程”中处理的数据,而无需使用“调用”或其他方法? (我们听说在打印'线程'内处理的数据时为了避免'跨线程',使用额外的'定时器对象'将数据分散到'定时器事件'中经常被使用,因为它既没有益处也没有害处)。

+0

不确定你的意思。你根本没有在你的代码中使用invoke,你需要它'timer_Tick'和'Work()' – gideon 2012-01-16 07:16:22

+0

'effective'是什么意思? – 2012-01-16 07:17:30

+0

也看看使用SynchronizationContext而不是在这里调用Invoke http://lostechies.com/gabrielschenker/2009/01/23/synchronizing-calls-to-the-ui-in-a-multi-threaded-application/ – sos00 2012-01-16 07:40:20

回答

1

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

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

BackgroundWorker s简单易懂,并且避免使用定时器。

Invoke比定时器更有效,因为在bCheckState成为true和正在更新的文本之间会有较少的延迟。由于您不会按照设定的时间间隔进行定时器轮询,因此它的CPU占用率也会更低。

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

作为另一种替代方案,BeginInvoke可用于更新表单而无需使用定时器,也无需线程必须等待调用完成。但是,如果引发异常,则线程可能无法找到,除非您还调用EndInvoke,这也将停止执行线程,直到调用完成。

他们都有自己的优点和缺点,你不能真正地调用任何特定的一个更“有效”的一般。

5

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

+0

谢谢你的建议 – KDJ 2012-01-20 00:20:05