Thanks to you all, it clears up lot of things for me on the foreach.
Here is what is says in the help example for CLose method on Process object.
Process myProcess;
myProcess = Process.Start("Notepad.exe");
// Close process by sending a close message to its main window.
myProcess.CloseMainWindow();
// Free resources associated with process.
myProcess.Close();
If I call the Close without calling CloseMainWindow or Kill, it does NOT throw exception nor does it do any damage(like closing applications). Thats why it was unclear to me if it frees resource of the myProcess object or that of Notepad.
In my case, I am not closing any process. I want to implement a Process Handler which implements IDisposable which instantiates the array in the constructor and does a close on each Process object of the array in the Dispose. The user could call publicly exposed Kill or CloseMainWindow functions as needed. May be I do not have to do this since Process is a managed object. But I wanted to clean up the objects as soon as possible as this could be used by windows service type applications.
Thanks
On the first question it really depends what the enumerator does if you are dealing with an enumerator .. some enumerators will deal directly with the object in question. Some may choose to use a snapshot of the data (note that this can be extremely beneficial when dealing with multi-threading scenarios).
In this particular case you are being returned an array ... Your code will be identical ...
It is quite simple to see this if you use reflector to look at the generated code but I am including below the native code generated .. you can see it is nearly identical.
Process.Close is a bit confusing .. it deals with the internal resources that the process class is holding .. process.CloseWindow() used in the example will send a windows message telling the process to close. Process.Kill() will kill the process immediately.
Cheers,
Greg Young
MVP - C#
http://codebetter.com/blogs/gregyoung
Native code for simple example...
namespace ConsoleApplication7
{
class Program
{
public static void Main() {
Process[] Processes = Process.GetProcesses();
00000000 push edi
00000001 push esi
00000002 push ebx
00000003 call 79A13448
00000008 mov esi,eax
foreach (Process p in Processes)
0000000a xor ebx,ebx
0000000c cmp dword ptr [esi+4],0
00000010 jle 00000053
00000012 cmp ebx,dword ptr [esi+4]
00000015 jae 0000009C
0000001b mov ecx,dword ptr [esi+ebx*4+0Ch]
{
Console.WriteLine(p.ProcessName);
0000001f cmp dword ptr [ecx],ecx
00000021 call 79C26558
00000026 mov edi,eax
00000028 cmp dword ptr ds:[02271084h],0
0000002f jne 0000003B
00000031 mov ecx,1
00000036 call 786FC654
0000003b mov ecx,dword ptr ds:[02271084h]
00000041 mov edx,edi
00000043 mov eax,dword ptr [ecx]
00000045 call dword ptr [eax+000000D8h]
0000004b add ebx,1
foreach (Process p in Processes)
0000004e cmp dword ptr [esi+4],ebx
00000051 jg 00000012
}
for (int i = 0; i < Processes.Length; i++)
00000053 xor ebx,ebx
00000055 cmp dword ptr [esi+4],0
00000059 jle 00000098
{
Process p = Processes
;
0000005b cmp ebx,dword ptr [esi+4]
0000005e jae 0000009C
00000060 mov ecx,dword ptr [esi+ebx*4+0Ch]
Console.WriteLine(p.ProcessName);
00000064 cmp dword ptr [ecx],ecx
00000066 call 79C26558
0000006b mov edi,eax
0000006d cmp dword ptr ds:[02271084h],0
00000074 jne 00000080
00000076 mov ecx,1
0000007b call 786FC654
00000080 mov ecx,dword ptr ds:[02271084h]
00000086 mov edx,edi
00000088 mov eax,dword ptr [ecx]
0000008a call dword ptr [eax+000000D8h]
for (int i = 0; i < Processes.Length; i++)
00000090 add ebx,1
00000093 cmp dword ptr [esi+4],ebx
00000096 jg 0000005B
00000098 pop ebx
}
}
00000099 pop esi
0000009a pop edi
0000009b ret
0000009c call 79443529
000000a1 int 3
But does foreach create more objects than necessary. Say you have a collection like
Process[] RunningProcesses = Process.GetProcesses();
foreach(Process P in _RunningProcesses)
{ if (P.....some code }
The other option is
for(int i=0; i < RunningProcesses.Length;i++)
{if (RunningProcesses.....some code }
Does the first method create a new Process object in each loop and set it equal to the array object ?
Also, an unrelated question to this thread but for Process object, does Process.Close() release memory associated with the "process object" that is pointing to a running process or of the running process itself. The document is confusing. I tried a .Close on the entire array. It did not disrupt my system but just wanted to be sure.
TIA