Solved

Problem with multithreading

Posted on 2003-11-26
12
261 Views
Last Modified: 2010-04-16
I have a mulitthreaded applicaiton, and I'm having a problem.  When data comes in from the server, it updates some of the controls on a form.  When I then make a call from the GUI thread (button click).  I'm getting an error everytime I hit this line:

foreach(ListViewItem item in contactListView.Items)
                        
that says.  "Error, thread was being stopped".  All the threads that aren't the GUI thread have
t.IsBackground = true;  

I haven't seen this error before and I am never explicitly stopping threads through code.  Any thoughts?
0
Comment
Question by:jjacksn
  • 6
  • 5
12 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9827153
Do you update the form directly from worker thread? You should use Invoke or BeginInvoke to do this, these functions serialize calls to the main thread:
http://www.codeproject.com/csharp/workerthread.asp
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9827634
it is thread safe. (I think).  I'm still having that problem.  Are these symptoms what i would find if it was not thread safe?  I had this multithreaded before and didn't have these problems.  I changed a lot of the code and now it is happening.  
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 9827774
You have to synchronize the calls which access the controls of the GUI.
Each control's method starts like:

pulic void AControlMethod(ParamType someParam)
{
    if (Thread.Current != threadCreatedThisControl)
    {
        throw new Exception();
    }
    .... Implemenation of the method....
}

You can only call one method from a foreign thread: Invoke(Delegate, object[])
Where "Delegate" is the delegate to the method you want to invoke (e.g. Show()) and "object[]" is an array of parameters to pass to the method.
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9827824
Ok, I have a problem with the Invoking:

I am creating a new instance of the object (the constructor calls InitializeComponents)

When I make a call that then calls invoke:
This method is inside of the form that is getting updated,
ReloadData() gets called from outside of the form.  


public void ReloadData()
{
                  if(this.Loaded)
                  {
                        this.reloadDataOnUnload = true;
                        return;
                  }
                  this.BeginInvoke(m_DelegateReload, null);
            /*      ThreadStart start = new ThreadStart(ReloadDataHelper);
                  Thread t = new Thread(start);
                  t.IsBackground = true;
                  t.Start();*/
            }

The error is that Invoke cannot be called until the main window Handle is created.  However, I am never creating the window handles.  I am pulling the controls out of a panel and loading them into the main window (so I can acheive the same effect as outlook where you click on the button and and then controls in the window change).  Can I not use invoke in this case?  
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 9827910
I'm sure Outlook does it differently. You cannot access the controls properties as long they don't exist on a window (= as long they don't have a handle). You can create them invisible and then change the visibility.

From SDK help:
Executes the specified delegate asynchronously with the specified arguments, on the thread that the control's underlying handle was created on.
public virtual IAsyncResult BeginInvoke(Delegate, object[]);
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9828302
Oh, I'm sure Outlook doesn't it differently as well.  

The basic mechanism I have been using is to create the Forms on a panel, then I switch which panel is loaded in my Main Window.  So I am never actually calling form.Show() or creating the window.  This is working fine, except for what I am talking about.  When I run the method from the GUI thread, it works.  When I run the method by starting a seperate thread when the button is clicked, I have the problem I was talking about.  

If I quickwatch the listViewItem, many of the fields are not populated correctly, but some are.  I'm confused why multithreading would cause these fields not be populated correctly?  (Nothing is happening in my test cases in the main GUI thread when this sepearte thread is running).
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 10

Expert Comment

by:ptmcomp
ID: 9830084
Try to create the controls, set the owner window but leave them invisible till everything is loaded. You must create the controls in the main thread! That's a restriction of .net framework.
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9842041
I think what is happening is that I am calling invoke on the class object, which doesn't have a main window.  I think if i call it on the control, I should be fine.  will try tommorrow and let you know.
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9843583
If I have a long operation (that contacts a server and displays the results in a list view) that I want to run in a seperate thread, do I call BeginInvoke on the whole operation/function as a deleagte?  or do I just create a delegate to wrap around the ListView.Items.Add(listViewItem item)?  and call it in the function that is run in a seperate thread?
0
 
LVL 10

Accepted Solution

by:
ptmcomp earned 250 total points
ID: 9847678
> I think if i call it on the control, I should be fine.
No, the window must be associated with a windows message queue. I think that's only the case if it has a parent window.
The delegate will run in its own thread so for any manipulation of the GUI you need to call Control.Invoke to synchronize the calls.
0
 
LVL 5

Author Comment

by:jjacksn
ID: 9850935
So is there no way to accomplish thread safety the way I currently have it structured?  
0
 
LVL 10

Expert Comment

by:ptmcomp
ID: 10022445
Yes, I think you have to change the structure of your code :o(. (In Win32 your code would probably work but .net has more restrictions.)
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now