Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Problem with multithreading

Posted on 2003-11-26
12
Medium Priority
?
270 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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 1000 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Najam
Having new technologies does not mean they will completely replace old components.  Recently I had to create WCF that will be called by VB6 component.  Here I will describe what steps one should follow while doing so, please feel free to post any qu…
Introduction Although it is an old technology, serial ports are still being used by many hardware manufacturers. If you develop applications in C#, Microsoft .NET framework has SerialPort class to communicate with the serial ports.  I needed to…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…

610 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