Jan Abramek
Jan Abramek

Reputation: 138

Making comparision in one thread between values from another thread C#

I want to use BackgroundWorker in my application. And I've learned, that when I want to do this:

buttonStart.Enabled = false;

in main thread, with another thread I should do it like this:

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

But when it goes to comparision operations:

if(tabControlDbSwitch.SelectedIndex == 0)

it doesn't works. So, here is my question:

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

And maybe you've got some hints for me, 'cause I'm totally newbie in multi threading, but I want to learn it as fast as possible.

I.e. I've heard that sometimes it will be better to use BeginInvoke than Invoke, but I don't know why and when.

Upvotes: 1

Views: 65

Answers (2)

Idle_Mind
Idle_Mind

Reputation: 39122

Here's another approach that actually allows the Invoke() to RETURN a value.

This way your code flows a little better:

    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;
        }
    }

Upvotes: 0

Deepak Bhatia
Deepak Bhatia

Reputation: 6276

CheckSelection is the function that you invoke from the function where this if code was return

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

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

You said you have heard that sometimes it will be better to use BeginInvoke than Invoke, but I don't know why and when. invoke and begin invoke are of two types delegate and control. In your example you are using Contol.Invoke

  • Delegate.Invoke: Executes synchronously, on the same thread.
  • Delegate.BeginInvoke: Executes asynchronously, on a threadpool thread means the function that is invoked in begin invoke will be executed on a new thread from a thread pool and you can continue doing your operation on same thread (Parallel execution).
  • Control.Invoke: Executes on the UI thread, but calling thread will wait for completion of the invoked function before continuing.
  • Control.BeginInvoke: Executes on the UI thread, and calling thread will not wait for completion of invoked function. Yes it is advisable that we use Control.BeginInvoke rather then Control.Invoke as you don't have to worry about deadlocks.

For example, if you remove the code

if(tabControlDbSwitch.InvokeRequired)

and always use

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

and in some case this function is invoked from UI main thread then your code will hang and result in deadlock.

Upvotes: 1

Related Questions