【问题标题】:Making comparision in one thread between values from another thread C#在一个线程中比较来自另一个线程的值 C#
【发布时间】:2013-10-10 11:45:38
【问题描述】:

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

【问题讨论】:

    标签: c# multithreading comparison-operators


    【解决方案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 主线程调用的,那么您的代码将挂起并导致死锁。

    【讨论】:

      【解决方案2】:

      这是另一种实际上允许 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;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2021-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-13
        • 2013-03-08
        相关资源
        最近更新 更多