Muti Threading In For/Foreach and DataTable example
class Program
{
static void Main(string[] args)
{
Threader t = new Threader();
List<string> lst = new List<string>();
for (int i = 0; i < 1000; i++)
lst.Add("number " + i);
t.RunThreadsWithControl(lst, 110);
t.PrintPrintedList(); //just to oversee that all numbers got printed
Console.WriteLine("Done");
Console.ReadKey();
}
}
class Threader
{
List<bool> globalThreadsFinished;
public bool AllThreadsFinished
{
get
{
foreach (bool item in globalThreadsFinished)
if (!item)
return false;
return true;
}
}
List<string> printedList;
public void PrintPrintedList()
{
foreach (string s in printedList)
Console.WriteLine(s);
}
public void RunThreadsWithControl(List<string> list, int threadsAtOneTime)
{
printedList = new List<string>();
for (int i = 0; i < list.Count; i++)
{
int j = i;
globalThreadsFinished = new List<bool>();
while (j < list.Count)
{
if ((i + threadsAtOneTime) >= list.Count)
threadsAtOneTime = list.Count - i;
globalThreadsFinished.Add(false);
int boolIndex = globalThreadsFinished.Count - 1;
string value = list[j];
Thread t = new Thread(() => HandleSingleThread(value , boolIndex));
t.Start();
if ((j + 1) >= (i + threadsAtOneTime))
break;
++j;
}
while (!AllThreadsFinished)
{
Thread waitThread = new Thread(() => WaitThread(100));
waitThread.Start();
waitThread.Join();
}
//this is optional, just to actualy see that the app actualy waits for stops
Console.WriteLine("AllThreadsFinished");
Thread waitThread2 = new Thread(() => WaitThread(1500));
waitThread2.Start();
waitThread2.Join();
//back to the must
globalThreadsFinished.Clear();
i = j;
}
}
void HandleSingleThread(string s, int boolIndex)
{
if (!printedList.Contains(s))
printedList.Add(s);
for (int i = 0; i < 100; i++)
Console.WriteLine(s);
globalThreadsFinished[boolIndex] = true;
}
void WaitThread(int mls)
{
Thread.Sleep(mls);
}
}
}
remember that if HandleSingleThread is calling sub-method u should probably make them as threads too cuz otherwise the program might cross-thread with them and u wont notice, and best to do there Thread.Join().
P.S. - just to state the obvious - the lst from Main can be DataTable.Rows, and just send a DataRow or ANY enumerator (da) and handle it right in your SingleThread method
also for the protocol this works too:
class Program
{
static void Main(string[] args)
{
int max = 5;
Thread[] tArr = new Thread[max];
for (int i = 0; i < max; i++)
{
int i2 = i;
tArr[i] = new Thread(() => Print(i2.ToString()));
tArr[i].Start();
}
for (int i = 0; i < max; i++)
{
tArr[i].Join();
}
Console.WriteLine("Done");
Console.ReadKey();
}
static void Print(string str)
{
for (int i = 0; i < 10; i++)
Console.WriteLine(str);
}
}
if u use this it is advised to run tArr and make them all null or stuff gets slow
{
static void Main(string[] args)
{
Threader t = new Threader();
List<string> lst = new List<string>();
for (int i = 0; i < 1000; i++)
lst.Add("number " + i);
t.RunThreadsWithControl(lst, 110);
t.PrintPrintedList(); //just to oversee that all numbers got printed
Console.WriteLine("Done");
Console.ReadKey();
}
}
class Threader
{
List<bool> globalThreadsFinished;
public bool AllThreadsFinished
{
get
{
foreach (bool item in globalThreadsFinished)
if (!item)
return false;
return true;
}
}
List<string> printedList;
public void PrintPrintedList()
{
foreach (string s in printedList)
Console.WriteLine(s);
}
public void RunThreadsWithControl(List<string> list, int threadsAtOneTime)
{
printedList = new List<string>();
for (int i = 0; i < list.Count; i++)
{
int j = i;
globalThreadsFinished = new List<bool>();
while (j < list.Count)
{
if ((i + threadsAtOneTime) >= list.Count)
threadsAtOneTime = list.Count - i;
globalThreadsFinished.Add(false);
int boolIndex = globalThreadsFinished.Count - 1;
string value = list[j];
Thread t = new Thread(() => HandleSingleThread(value , boolIndex));
t.Start();
if ((j + 1) >= (i + threadsAtOneTime))
break;
++j;
}
while (!AllThreadsFinished)
{
Thread waitThread = new Thread(() => WaitThread(100));
waitThread.Start();
waitThread.Join();
}
//this is optional, just to actualy see that the app actualy waits for stops
Console.WriteLine("AllThreadsFinished");
Thread waitThread2 = new Thread(() => WaitThread(1500));
waitThread2.Start();
waitThread2.Join();
//back to the must
globalThreadsFinished.Clear();
i = j;
}
}
void HandleSingleThread(string s, int boolIndex)
{
if (!printedList.Contains(s))
printedList.Add(s);
for (int i = 0; i < 100; i++)
Console.WriteLine(s);
globalThreadsFinished[boolIndex] = true;
}
void WaitThread(int mls)
{
Thread.Sleep(mls);
}
}
}
remember that if HandleSingleThread is calling sub-method u should probably make them as threads too cuz otherwise the program might cross-thread with them and u wont notice, and best to do there Thread.Join().
P.S. - just to state the obvious - the lst from Main can be DataTable.Rows, and just send a DataRow or ANY enumerator (da) and handle it right in your SingleThread method
also for the protocol this works too:
class Program
{
static void Main(string[] args)
{
int max = 5;
Thread[] tArr = new Thread[max];
for (int i = 0; i < max; i++)
{
int i2 = i;
tArr[i] = new Thread(() => Print(i2.ToString()));
tArr[i].Start();
}
for (int i = 0; i < max; i++)
{
tArr[i].Join();
}
Console.WriteLine("Done");
Console.ReadKey();
}
static void Print(string str)
{
for (int i = 0; i < 10; i++)
Console.WriteLine(str);
}
}
if u use this it is advised to run tArr and make them all null or stuff gets slow
Comments
Post a Comment