1

I am wanting to progmatically create a new threads that programatically creates a browser tab and performs events within that browser tab. The problem is that I get a message saying I cannot perform UI affects on UI objects in the parent thread.

So I need to find a way to tell the new thread to use the UI objects of the primary thread. This should be easy to do right?

Here is the snippet of code so far that I'm working with:

//....to this point we have told the code to run selected items in a datagrid. Each will have it's own thread.


            if (row.Cells[1].Value.ToString() == "True")
            {
                count_active++;
                //begin multithreading
                Thread this_thread = new Thread(() => f_play_campaign(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString()));
                this_thread.Name = "thread_" + row.Cells[0].Value.ToString();
                this_thread.IsBackGround = true;
                this_thread.Start();

            }

        }

        if (count_active == 0)
        {
            MessageBox.Show("No campaigns are selected!");
        }
    }


    private void f_play_campaign(string project_id, string tab_name)
    {
        //MessageBox.Show(tab_name);
        //add new tab
        string browsername = f_create_new_tab(tab_name); //this is where the code breaks!
        Control browser = f_get_control_by_name(browsername);

        //MessageBox.Show(browser.ToString());

        //... do more code

Is there an easy way to tell the thread to use the UI objects of the primary thread? I could not figure out how to use Invoke() when I'm trying to get a return value from my method f_create_new_tab(), and I'm so new at this that I've not figured out how to use a background worker in the same fashion as threads.

I'll continue reading other threads on this issue but hopefully someone knows a extremely easy an elegant solution that would satisfy a php programmer like me.

2 Answers 2

2

I had to deal with this issue a few days earlier. It's fairly easy to solve:

Thread this_thread = new Thread(() =>
    this.Invoke((MethodInvoker)delegate
    {
        f_play_campaign(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString();
    }));

Basically you need to pass into Invoke a MethodInvoker delegate, which is defined as public delegate void MethodInvoker().

If you wanted to use BackgroundWorker it's very similar:

 BackgroundWorker worker = new BackgroundWorker();
 worker.DoWork += (s, e) =>
 {
     this.Invoke((MethodInvoker) delegate { MyJobHere(); });
 };

 // Do the work
 worker.RunWorkerAsync();

If you want to return some value, you could do something like this:

BackgroundWorker worker = new BackgroundWorker();
int value;
worker.DoWork += (s, e) =>
{
    this.Invoke((MethodInvoker) delegate { value = DoSomething(); });
};

worker.RunWorkerAsync();


// do other processing
while (worker.IsBusy)
{
    // Some other task
}

// Use the value
foo(value);
Sign up to request clarification or add additional context in comments.

2 Comments

Hey Mike, Thanks that makes sense and it definitely solved the conflict. I have the an issue where it seems that it will not move forward in the selected items loop until f_play_campaign() has ran it's course, So the threads cannot/do-not run simultaneously. Any advice? Also, tried to use the backgroundworker version and it seems that there is ; somewhere missing, but I could not see where so as to fix it.
@atwellpub: I unfortunately can't say more without really seeing what your code looks like. What you have provided isn't enough to explain the behavior you're getting.
1

Add a new method:

    private void f_play_campaign_Async(string project_id, string tab_name)
    {
        Action<string, string> action = f_play_campaign; 
        this.Invoke(action, project_id, tab_name);
    }

Modify construction of the therad to call this method instead:

Thread this_thread = new Thread(() => f_play_campaign_Async(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString()));

1 Comment

I'm trying this out as well, and it seems I lose the ability to create & run multiple threads. It seems that the method f_play_campaign_Async() requires completion of it's tasks before the loop will continue to run and create any additional threads.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.