Sure thing, Jon. I love your explanation page -- but it's much too
wordy. I skimmed it and found that my assumptions before clicking your
link were right -- you wanted a compilable program that didn't have
extraneous logic.
Here it goes: (this compiles)
-------------------------------------------------------------------------------------------------------------------------
"Form1.cs"
-------------------------------------------------------------------------------------------------------------------------
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Navigation_Creator_2
{
public delegate void doUpdateUIthreadCounter();
public partial class Form1 : Form
{
private Thread[] oThreads = new Thread[5000];
private int iThreadIndex = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void buttonRunProgram_Click(object sender, EventArgs e)
{
// Create a new thread to separate it from the UI
Thread tMain = new Thread(new
ThreadStart(doFoldersThread));
tMain.Name = "Main Thread";
tMain.IsBackground = true;
tMain.Start();
// add it to our watch list of threads.
addThreadToThreadWatch(tMain, tMain.Name);
Thread tWatcher = new Thread(new
ThreadStart(awakenTheWatcher));
tWatcher.Name = "The Watcher";
tWatcher.IsBackground = true;
tWatcher.Start();
/* disable the RUN button - we don't want threads trying
* to access the same files */
buttonRunProgram.Enabled = false;
}
private void addThreadToThreadWatch(Thread t, string
strThreadName)
{
lock (oThreads)
{
if (t.IsAlive)
{
// add this thread to our stack list.
oThreads[iThreadIndex] = t;
// tmpFileWriter.WriteLine(strThreadName + " added
to watch. " + t.Name + "/" + t.ToString());
}
}
}
void doUpdateUIthreadCounter()
{
if (InvokeRequired)
{
BeginInvoke(new
doUpdateUIthreadCounter(invokeUpdateUIthreadCounter) /*, new object[] {
strThreadName }*/);
}
else
{
lock (oThreads)
{
textBoxThreadsRunning.Text += "[" +
iThreadIndex.ToString() + "] ";
}
}
}
private void invokeUpdateUIthreadCounter()
{
lock (oThreads)
{
textBoxThreadsRunning.Text += "[" +
iThreadIndex.ToString() + "] ";
}
}
private void awakenTheWatcher()
{
bool bStayAwake = false;
/* As long as the watcher is awake, he will watch the
threads.
* once all the threads are dead, he too, will pass. */
do
{
bStayAwake = false;
Thread.Sleep(500);
lock (oThreads)
{
iThreadIndex = 0;
int iCounter = 0;
while (oThreads[iCounter] != null)
{
if (oThreads[iCounter].IsAlive)
{
iThreadIndex++;
bStayAwake = true;
}
iCounter++;
}
}
// update the THREAD counter
doUpdateUIthreadCounter();
} while (bStayAwake);
}
private void doFoldersThread()
{
// where to start
string strCurrentDir = "C:\\Inetpub\\wwwroot\\";
// get all the directories in this area...
// string[] strDirectories =
Directory.GetDirectories(strCurrentDir);
// get all the .html files in this area
// string[] strFiles = Directory.GetFiles(strCurrentDir,
"*.html");
// Set up a log file... we'll list the directories and
files we find here.
TextWriter tmpFileWriter = new
StreamWriter("C:\\Inetpub\\wwwroot\\content\\logfile.tmp");
if (tmpFileWriter != null)
{
// First, we search the files in the ROOT area...
DirSearchFiles(strCurrentDir, tmpFileWriter, false);
// Then we recursively go through the directories...
DirSearch(strCurrentDir, tmpFileWriter);
}
else
{
// it didn't work
tmpFileWriter.WriteLine(DateTime.Now.TimeOfDay.ToString() +
"\tERROR creating LOG file.");
}
// Close the log file.
tmpFileWriter.Close();
}
private void DirSearch(
string sDir,
TextWriter tmpFileWriter)
{
// open the log file to write to...
try
{
/* This boolean will tell us whether or not, during our
look through
* every file in a given directory, if we have already
listed that
* directory as having .html files in it. */
bool bDoneAlready = false;
/* Go through each directory at the current level... */
foreach (string d in Directory.GetDirectories(sDir))
{
bDoneAlready = false; // reset the boolean
/* Go through all of the files at the current
level. If one
* is an .html file, then we must list this
directory
* (and add it to the stack). */
DirSearchFiles(d, tmpFileWriter, bDoneAlready);
/* Recursively do this same routine for each
directory! */
DirSearch(d, tmpFileWriter);
}
}
catch (System.Exception error)
{
// Update UI:
// Let the user know what went wrong.
tmpFileWriter.WriteLine(DateTime.Now.TimeOfDay.ToString() +
error.ToString());
}
}
private void DirSearchFiles(
string d,
TextWriter tmpFileWriter,
bool bDoneAlready)
{
foreach (string f in Directory.GetFiles(d, "*.html"))
{
if (File.Exists(f))
{ // we have a directory that has valid .html files!
if (!bDoneAlready)
{
bDoneAlready = true;
tmpFileWriter.WriteLine(d);
}
else
{
tmpFileWriter.WriteLine("\t" + f);
}
// ADD TO DIRECTORY STACK
ThreadDoFile objContainer = new ThreadDoFile(d, f);
Thread objThread = new Thread(new
ThreadStart(objContainer.ThreadFunction));
objThread.Name = "File Thread " + f;
objThread.Start();
addThreadToThreadWatch(objThread, objThread.Name);
}
}
}
}
class ThreadDoFile
{
// directory for this file...
string strDirectory;
// what it says... but includes the path.
string strFileName;
public ThreadDoFile(
string strDirectoryPassed,
string strFileNamePassed)
{
strDirectory = strDirectoryPassed;
strFileName = strFileNamePassed;
//strPageName = "ERROR: No Page Name Instantiated";
}
public void ThreadFunction()
{
// strFileName is a variable of this class.
string strCurrentFile = strFileName;
// open the temporary file to write to...
TextWriter logFileWriter =
doOpenFileForWriting(strCurrentFile + ".tmp");
/* try to take the current file and read until we find
<CREATENAV>
* and then we can insert new navigation information here
*/
logFileWriter.WriteLine(DateTime.Now.TimeOfDay.ToString() + "\tStarting
ThreadDoFile() " + strFileName);
// doStuff();
logFileWriter.WriteLine(DateTime.Now.TimeOfDay.ToString() + "\tEnding
ThreadDoFile() " + strFileName);
logFileWriter.Close();
}
private TextWriter doOpenFileForWriting(string strFileName)
{
try
{
// create a writer and open the file
TextWriter tmpFileWriter = new
StreamWriter(strFileName);
return tmpFileWriter;
}
catch (Exception error)
{
// Let the user know what went wrong.
return null;
}
}
}
}
-------------------------------------------------------------------------------------------------------------------------
"Form1.Designer.cs"
-------------------------------------------------------------------------------------------------------------------------
namespace Navigation_Creator_2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.buttonRunProgram = new System.Windows.Forms.Button();
this.textBoxThreadsRunning = new
System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// buttonRunProgram
//
this.buttonRunProgram.Font = new
System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonRunProgram.Location = new
System.Drawing.Point(13, 13);
this.buttonRunProgram.Name = "buttonRunProgram";
this.buttonRunProgram.Size = new System.Drawing.Size(75,
29);
this.buttonRunProgram.TabIndex = 0;
this.buttonRunProgram.Text = "Start";
this.buttonRunProgram.UseVisualStyleBackColor = true;
this.buttonRunProgram.Click += new
System.EventHandler(this.buttonRunProgram_Click);
//
// textBoxThreadsRunning
//
this.textBoxThreadsRunning.BackColor =
System.Drawing.SystemColors.InactiveCaptionText;
this.textBoxThreadsRunning.Font = new
System.Drawing.Font("Verdana", 9F, System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxThreadsRunning.ForeColor =
System.Drawing.Color.OliveDrab;
this.textBoxThreadsRunning.Location = new
System.Drawing.Point(13, 49);
this.textBoxThreadsRunning.Multiline = true;
this.textBoxThreadsRunning.Name = "textBoxThreadsRunning";
this.textBoxThreadsRunning.ScrollBars =
System.Windows.Forms.ScrollBars.Vertical;
this.textBoxThreadsRunning.Size = new
System.Drawing.Size(757, 405);
this.textBoxThreadsRunning.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(782, 466);
this.Controls.Add(this.textBoxThreadsRunning);
this.Controls.Add(this.buttonRunProgram);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button buttonRunProgram;
private System.Windows.Forms.TextBox textBoxThreadsRunning;
}
}