My problem is passing the this.folderFolder instance method to ThreadStart ctor. I step through it with dirAssThread and watch it update the instance data member correctly and complete, then I trap back to
if (dirAssThread.IsAlive) completeThread(-1); //***ie abort
and find that the data member of the same this instance that I passed with the method to the ThreadStart ctor has miraculously reset itself to 0!
Here are the other functions
using System;
using System.IO;
using System.Threading;
namespace MonitorService
{
struct myStruct
{
long bytesSzMember;
Thread dirAssThread;
private Object thisLock;
private void completeThread(long bytesSzNew)
{
lock (thisLock)
{
if (bytesSzNew == -1)
{
dirAssThread.Abort();
Console.WriteLine("A thread timed out.");
}
else
{
bytesSzMember = bytesSzNew;
Console.WriteLine("A thread update size.");
}
}
}
private void folderFolder()
{
long bytesSzNew = 0;
DirectoryInfo di = new DirectoryInfo("C:\\SomeDir");
DirectoryInfo[] directories = di.GetDirectories("*",SearchOption.AllDirectories);
FileInfo[] files = di.GetFiles("*",SearchOption.AllDirectories);
foreach (FileInfo file in files)
{
bytesSzNew += file.Length;
}
completeThread(bytesSzNew);
}
private void updateSize()
{
thisLock = new Object();
dirAssThread = new Thread(new ThreadStart(this.folderFolder));
dirAssThread.Start();
Thread.Sleep(5000);
if (dirAssThread.IsAlive) completeThread(-1);
}
}
}
Update
After the question title update, the problem you are seeing is that structs are copied on reference. You are passing a copy of your struct when assigning the delegate to the thread, and it is this copy that will be updated by the thread. When you do your check in
completeThreadit is against the original which has not been updated.Use a class instead of a struct.
Alternate Solution
I would suggest using wait handles instead of sleeps and thread aborts, as
Thread.Abortis considered a dangerous practice and should be avoided (quite easily in this case). I propose the following solution which is a recursive version that will not follow circular references (so there is no need to abort in reality, the code can be removed if you do not want a timeout facility).Update
As we now have circular reference detection, the threading and abort code can be removed as that was previously there to abort the thread if it was in an endless loop – no need for that now: