1

我想在我的应用程序中使用 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 更好,但我不知道为什么以及何时使用。

4

2 回答 2

1

CheckSelection 是您从返回 this if 代码的函数调用的函数

        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 更好,但我不知道为什么以及何时使用。调用和开始调用有委托和控制两种类型。在您的示例中,您使用的是 Contol.Invoke

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

例如,如果您删除代码

if(tabControlDbSwitch.InvokeRequired)

并始终使用

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

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

于 2013-10-10T12:05:49.267 回答
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;
        }
    }
于 2013-10-10T14:20:51.433 回答