Solved

Problem with multithreading

Posted on 2003-11-26
12
263 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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

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

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Vb.net dynamic formulas in runtime 11 75
Error in JQuery 5 54
Error on link 14 48
VB.NET (2008) - Refactoring Question 2 21
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

832 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