1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
class ThreadRun
{
public delegate void ParameterLessMethod();
protected virtual Queue<ParameterLessMethod> WorkQueue { get; set; }
protected virtual int OriginalThreadId { get; set; }
public ThreadRun()
{
WorkQueue = new Queue<ParameterLessMethod>();
OriginalThreadId = Thread.CurrentThread.ManagedThreadId;
}
public virtual void Invoke(ParameterLessMethod method)
{
if(method == null)
return;
if (Thread.CurrentThread.ManagedThreadId == OriginalThreadId)
method.Invoke();
else
{
lock (WorkQueue)
{
WorkQueue.Enqueue(method);
}
}
}
public virtual bool WorkPending
{
get
{
lock (WorkQueue)
{
return WorkQueue.Count > 0;
}
}
}
public virtual void DoEvents()
{
if (Thread.CurrentThread.ManagedThreadId != OriginalThreadId)
throw new InvalidOperationException("Cette méthode doit être appelée à partir du thread principal");
ParameterLessMethod currentMethod = null;
while (true)
{
lock (WorkQueue)
{
if (WorkQueue.Count < 1)
break;
else
currentMethod = WorkQueue.Dequeue();
}
Invoke(currentMethod);
}
}
}
static int working = 0;
static ThreadRun threadRun = new ThreadRun();
static void Main(string[] args)
{
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 20; i++)
{
working++;
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
threads.Add(t);
}
while (working > 0 || threadRun.WorkPending)
{
threadRun.DoEvents();
}
Console.ReadLine();
}
public static void ThreadMethod()
{
threadRun.Invoke(new ThreadRun.ParameterLessMethod(delegate
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}));
working--;
}
}
} |
Partager