Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Conversion from C# to VB.NET
Message
De
19/04/2013 08:56:27
 
 
À
19/04/2013 08:01:57
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:
01571470
Vues:
38
>>>>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
>>>
Interesting. It's cleverer than I thought. But :
        static void TestWithForEach()
>>        {
>>             int l = Tables.Length;
>>            ReInitializeTables();
>>            Console.WriteLine(Tables[l]);
>>
>>            Console.ReadLine();
>>        }
>
>
>Would fail - even without ReInitializeTables()

Duh. OK : Console.WriteLine(Tables[l-1]);

>Bear in mind that Michel stores a refernce of App.oApp.Tables in another object oProcess and continues working with that reference. When App.oApp.Tables is replaced by a new occurrence - oProcess continues to use the previous object

That's what I don't get.
oProcess.Tables = App.oApp.Tables;
It's still a reference. If you change App.oApp.Tables then you change oProcess.Tables ?
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform