Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Conversion from C# to VB.NET
Message
De
19/04/2013 05:58:20
 
 
À
19/04/2013 04:53:55
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Versions des environnements
Environment:
VB 9.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Web
Divers
Thread ID:
01571173
Message ID:
01571458
Vues:
43
>Still don't see it. Given this:
       public string[] Tables = new string[] { "One", "Two", "Three" };
>     
>
>        public void UseTables()
>        {
>            foreach (string s in Tables)
>            {
>                //Do something
>                System.Threading.Thread.Sleep(1000);
>            }
>        }
>
>        public void LoadDataDictionary()
>        {
>            string[] tables = new string[]{"One","Two"};
>            Tables = tables;
>        }
>
If, for example, LoadDataDictionary() runs on one thread whilst UseTables() is running on another you've got problems...


My first thought was - this has to work.

So, I have tested this on the same thread

A foreach is nothing but an enumerator. So, I tested with (a) an enumerator and (b) with a foreach loop
In the middle of the loop , I assign a new Table - mind you, I do not change the contents of Tables - just replace it with a new occurrence

And what I expected is true - it works and continues with the 'old' Tables

The reason it continues to work is that the foreach, when it starts, stores a reference to Tables in a local variable and continues to work with the local variable
During the first iteration, Tables is replaced with a new array, but the loop continues to work with the reference it saved at the beginning of the loop
The old object Tables continues to be referenced during the life time of the loop and during that time will not be garbage collected

IldAsm listing of foreach at the end
	public class AClass
	{
		public static string[] Tables;

		public static void Main()
		{
			TestWithEnumerator();
			TestWithForEach();
		}

		static void TestWithEnumerator()
		{
			InitializeTables();
			var enumerator = Tables.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Console.WriteLine(enumerator.Current);
				ReInitializeTables();
			}
			Console.ReadLine();
		}
		static void TestWithForEach()
		{
			InitializeTables();
			foreach (var x in Tables )
			{
				Console.WriteLine(x);
				ReInitializeTables();
			}
			Console.ReadLine();
		}

		public static void InitializeTables()
		{
			string[] tables = new string[] { "one", "two", "three" };
			Tables = tables;
		}

		public static void ReInitializeTables()
		{
			string[] tables = new string[] { "four", "five" };
			Tables = tables;
		}
	}
ild
.method private hidebysig static void  TestWithForEach() cil managed
{
  // Code size       58 (0x3a)
  .maxstack  2
  .locals init ([0] string x,
           [1] string[] CS$6$0000,
           [2] int32 CS$7$0001,
           [3] bool CS$4$0002)
  IL_0000:  nop
  IL_0001:  call       void CoreTest.AClass::InitializeTables()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldsfld     string[] CoreTest.AClass::Tables                     loads static field Tables on the stack
  IL_000d:  stloc.1                                                                                   and stores it locally
  IL_000e:  ldc.i4.0
  IL_000f:  stloc.2
  IL_0010:  br.s       IL_0029
  IL_0012:  ldloc.1
  IL_0013:  ldloc.2
  IL_0014:  ldelem.ref
  IL_0015:  stloc.0
  IL_0016:  nop
  IL_0017:  ldloc.0
  IL_0018:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001d:  nop
  IL_001e:  call       void CoreTest.AClass::ReInitializeTables()
  IL_0023:  nop
  IL_0024:  nop
  IL_0025:  ldloc.2
  IL_0026:  ldc.i4.1
  IL_0027:  add
  IL_0028:  stloc.2
  IL_0029:  ldloc.2
  IL_002a:  ldloc.1
  IL_002b:  ldlen
  IL_002c:  conv.i4
  IL_002d:  clt
  IL_002f:  stloc.3
  IL_0030:  ldloc.3
  IL_0031:  brtrue.s   IL_0012
  IL_0033:  call       string [mscorlib]System.Console::ReadLine()
  IL_0038:  pop
  IL_0039:  ret
} // end of method AClass::TestWithForEach
Gregory
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform