64660

C# List Manipulation - Output Different When Stepping Through vs. Running

Question:

I'm a C# newbie and I'm really confused about something I'm trying to do for a project in a C# class.

The assignment is some list manipulation in C#.

The program accepts a list of items in the text box, then iterates through those items, creating multiple copies of the list. It randomly resizes each copy of the list to between 3 and all items. It then outputs all the copies.

The problem I'm having is that when I step through this program with the debugger, I get the expected output. The same happens if I display a message box after each iteration (as I have in the code below).

However, if I just run the program straight through, I get a different output. Instead of variations in the lists, all the copies of the list are exactly the same.

If you see in the code I've commented "// FIRST DEBUG MESSAGEBOX" and "// SECOND DEBUG MESSAGEBOX". If the first debug messagebox code is left in there, the output is as expected...multiple versions of the list are output with random lengths between 3 and all items.

However, and this is where I'm confused...if you comment out the first debug messagebox code, you get a different result. All versions of the list output are the same length with no variation.

Any help would be appreciated! Here's the code I have so far...sorry if it's terrible - I'm new at C#:

public partial class MainForm : Form { /** * Vars to hold raw text list items * and list items split by line */ String rawListItems = ""; List<string> listItems = new List<string>(); List<List<string>> textListItems = new List<List<string>>(); public MainForm() { InitializeComponent(); } private void cmdGo_Click(object sender, EventArgs e) { // store the contents of the list item text box this.rawListItems = txtListItems.Text; this.listItems.AddRange(Regex.Split(this.rawListItems, "\r\n")); // setup min and max items - max items all items int minItems = 3; int maxItems = this.listItems.Count; // We'll copy this list X times, X = same number of items in list for (int i = 0; i < this.listItems.Count; i++) { // make a copy of the list items List<string> listItemsCopy = new List<string>(this.listItems); // get a random number between min items and max items Random random = new Random(); int maxIndex = random.Next(minItems, maxItems + 1); // max is exclusive, hence the +1 // remove all elements after the maxIndex for (int j = 0; j < listItemsCopy.Count; j++) { if (j > maxIndex) { listItemsCopy.RemoveAt(j); } } // add the list copy to the master list this.textListItems.Add(listItemsCopy); // FIRST DEBUG MESSAGEBOX String tst = ""; foreach (string item in listItemsCopy) { tst += item + " ## "; } MessageBox.Show(tst); } // SECOND DEBUG MESSAGEBOX String output = ""; foreach (List<string> listitem in this.textListItems) { foreach (string item in listitem) { output += item + " ## "; } } MessageBox.Show(output); } }

Answer1:

Move the creation of Random out of the loop:

Random random = new Random();

By default, the constructor uses a default time based seed. In a tight loop, you may be getting 'the same' random generator instead of a different one with each loop.

When using MessageBoxes or single stepping, you are allowing the timer to run and getting 'a new' random generator in each loop.

Answer2:

I don't understand your assignment exactly, but this loop seems to be incorrect:

for (int j = 0; j < listItemsCopy.Count; j++) { if (j > maxIndex) { listItemsCopy.RemoveAt(j); } }

when you remove an element in the middle of a list, elements after that get shifted, so not all the elements after maxIndex get removed, as you might expect.

Answer3:

In circumstances where stepping through the code in a debugger affects the behaviour of the program, a useful alternative debugging technique is to use the <a href="http://msdn.microsoft.com/en-us/library/15t15zda.aspx" rel="nofollow">System.Diagnostics</a> namespace in particular the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.trace.aspx" rel="nofollow">Trace</a> class.

The Trace functions work much like Console.WriteLine(), you can trace a string or a format string plus an array of objects to populate the format string, e.g.:

Trace.TraceInformation("some message that tells me something"); Trace.TraceInformation("some useful format string {1}, {0}", new object[] {someObject, someOtherObject});

Recommend

  • How-to use FindItemWithText?
  • ManagedBean Params not accepted and Bean seemingly not in scope
  • Hiding a form, switch to a second form, close second form and unhide first form
  • Math in Redux-form. Adding Fields together
  • Birt script behaves differently via web viewer
  • Border Layout not working
  • Find exception hiding/swallowing in C# code in VS2013
  • Why is this piece of Javascript code so slow?
  • Needing help with JSON problems
  • How to label data points in matplotlib scatter plot while looping through pandas dataframes?
  • Set User Control's default event
  • jQuery ajax security
  • Reinitialise existing jQuery flexslider with new options
  • Laravel lmutator $this->attributes return 'Undefined index: id'
  • HALF_PTR Windows data type
  • Azure table query partial partitionkey guid match
  • How to set an entity field that does not exist on the table but does exists in the raw SQL as an ali
  • Can XOR be expressed using SKI combinators?
  • Count from each distinct date, fill in missing dates with zero
  • F#: In which memory area is the continuation stored: stack or heap?
  • Interpreting STRACE output - pipes and forks
  • Retaining data after updating application
  • Most efficient way to move table rows from one table to another
  • Using Generics on right hand side in Java 6?
  • How to handle elastic beanstalk deployment so it uploads only changed files
  • Filter strings with regex before casting to numeric
  • Implementing “partial void” in VB
  • How to define custom class, title, and target in Link Browser for content elements and the new rte_c
  • Custom Tabgroup Appcelerator
  • PHPUnit_Framework_TestCase class is not available. Fix… - Makegood , Eclipse
  • Projection media query: browser support and workarounds?
  • Different response to non-authenticated users and AJAX calls
  • jQuery tmpl and DataLink beta
  • SQL merge duplicate rows and join values that are different
  • Proper way to use connect-multiparty with express.js?
  • How to set the response of a form post action to a iframe source?
  • JTable with a ScrollPane misbehaving
  • unknown Exception android
  • failed to connect to specific WiFi in android programmatically
  • How can I use threading to 'tick' a timer to be accessed by other threads?