Click here to Skip to main content
15,907,906 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hello,

I am trying to create an application in which 2-4 threads gets data from different sources
and I have to show that data on my Form in a textbox.
I have taken a stringbuilder and i keep appending the data from different threads into it.
Also a timer with interval of 2 seconds, and on its tick event the whole stringbuilder data
is copied to the textbox. and after a particular length of stringbuilder (lets say) 50000, I clear it.

But sometimes I get this exception :

Message : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: chunkLength
TargetSite : System.String ToString()

I have searched and found somethings relative
http://social.msdn.microsoft.com/Forums/ar/netfxbcl/thread/1051ec1c-667f-4568-a528-027cb12c34f9

But i am not getting Textbox.Dispatcher.

Now I am not sure what should I do, and also i am not clear why this exception occurs.

Code :

C#
private void clock_Tick(object sender, EventArgs e)
 {
   try
   {
     txtMsg.Text = myClass.myStringBuilder.ToString();  //throws exception sometime
                
      if (myClass.myStringBuilder.Length == 50000)
      {
         myClass.myStringBuilder.Clear();
      }
   }
    catch (Exception ex)
    {
      //create error log
    }
 }




Thanks.
Posted
Comments
ZurdoDev 27-Feb-12 8:40am    
Index was out of range error means you are doing something in your class to try and access something that isn't there. If you don't share your code, how can we help?
El_Codero 27-Feb-12 8:46am    
Does it work if you check Length of myStringBuilder.Lenght >=50000 && myStringBuilder.Length != null) ?

With multi-threaded applications you need to actively take steps to synchronize your threads and data access. Since you are adding to and reading from the stringbuilder from multiple threads it could be in any state at any time.

Try something like this
public void AddString(string s)
{
  lock(this.LockObject)
  {
     StringBuilder.Add(s);
  }
} 
 
Share this answer
 
Comments
fjdiewornncalwe 27-Feb-12 10:04am    
Naturally. +5.
DeepsMann 28-Feb-12 0:41am    
Thanks Mark..
got it... :)
Using 2-4 threads and thread pooling, it is easy to stumble upon some resource conflicts. Remember to lock your StringBuilder whenever you access it.

Here are some tips if you've never used it:
Remember to distribute the same instance of your lock-token to all threads. The lock-token is just any object, like:
C#
object _myLockToken = new object();


Your code will then be something like:
C#
private void clock_Tick(object sender, EventArgs e)
{
  lock(_myLockToken)
  {
   try
   {
     txtMsg.Text = myClass.myStringBuilder.ToString();  //throws exception sometime
                
      if (myClass.myStringBuilder.Length == 50000)
      {
         myClass.myStringBuilder.Clear();
      }
   }
    catch (Exception ex)
    {
      //create error log
    }
  }
}


lock Statement (C# Reference)

I'm quite confident that this will help.
(Remember the BeginInvoke-pattern when updating the GUI)
 
Share this answer
 
Comments
[no name] 27-Feb-12 13:26pm    
An hour later an still the same response. What did you add? Oh, right, the link to the lock statement reference. Easy to build off an answer that has already been given rather than come up with your own I guess.
Amund Gjersøe 27-Feb-12 13:43pm    
Excuse me? We posted simultaneously. I posted the solution when the question was 10 minutes old, and so did you. Keep the record straight man. It is a pretty straight forward solution, so it is not a surprise that there comes two solutions that includes 'lock'.
[no name] 27-Feb-12 13:59pm    
My mistake on the time. I saw the comment time. But still nothing else new added.
DeepsMann 28-Feb-12 0:41am    
Amund, thanks..
its working now..
:)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900