在一个线程中比较来自另一个线程C#的值

时间:2013-10-10 11:45:39

标签: c# multithreading comparison-operators

我想在我的应用程序中使用BackgroundWorker。而且我已经了解到,当我想要这样做时:

buttonStart.Enabled = false;

在主线程中,另一个线程我应该这样做:

if (buttonStart.InvokeRequired) { buttonStart.Invoke(new Action(() => buttonStart.Enabled = false)); }
else buttonStart.Enabled = false;

但是当它进行比较操作时:

if(tabControlDbSwitch.SelectedIndex == 0)

它不起作用。 所以,这是我的问题:

if ((!tabControlDbSwitch.InvokeRequired && tabControlDbSwitch.SelectedIndex == 0) ||
    (tabControlDbSwitch.InvokeRequired && /*What should I write here?*/))

也许你有一些提示给我,因为我是多线程的新手,但我想尽快学习它。

即。我听说有时使用BeginInvoke比使用Invoke更好,但我不知道为什么以及何时。

2 个答案:

答案 0 :(得分:1)

CheckSelection是您从函数中调用的函数,该函数返回此代码

        public void CheckSelection()
    {
        if (tabControlDbSwitch.InvokeRequired)
        {
            tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));
        }
        else
            CheckTabSelection();
    }

    public void CheckTabSelection()
    {
        if (tabControlDbSwitch.SelectedIndex == 0)
        { 
            // Do my work .....
        }
    }

你说你听说有时候使用BeginInvoke比使用Invoke更好,但我不知道为什么以及何时。 invoke和begin invoke有两种类型委托和控制。在您的示例中,您使用的是Contol.Invoke

  • Delegate.Invoke:在同一个线程上同步执行。
  • Delegate.BeginInvoke:异步执行,在线程池线程上意味着在开始调用中调用的函数将在线程池的新线程上执行,您可以继续在同一线程上执行操作(并行执行)。 / LI>
  • Control.Invoke:在UI线程上执行,但调用线程将在继续之前等待调用函数的完成。
  • Control.BeginInvoke:在UI线程上执行,调用线程不会等待调用函数的完成。 是的,建议我们使用Control.BeginInvoke而不是Control.Invoke,因为您不必担心死锁。

例如,如果删除代码

if(tabControlDbSwitch.InvokeRequired)

并始终使用

tabControlDbSwitch.Invoke(new Action(() => { CheckTabSelection(); }));

在某些情况下,从UI主线程调用此函数,然后您的代码将挂起并导致死锁。

答案 1 :(得分:0)

这是另一种实际允许Invoke()返回值的方法。

这样你的代码就会更好一点:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        if (GetSelectedIndex(this.tabControlDbSwitch) == 0)
        {
            Console.WriteLine("Success!");
        }
    }

    private delegate int ReturnSelectedIndex(TabControl tb);
    private int GetSelectedIndex(TabControl tb)
    {
        if (tb.InvokeRequired)
        {
            return (int)tb.Invoke(new ReturnSelectedIndex(GetSelectedIndex), new Object[] { tb });
        }
        else
        {
            return tb.SelectedIndex;
        }
    }