您的位置:首页 > 其它

多线程实现

2013-11-09 22:57 176 查看
WorkState

public enum WorkState
{
Ready,
Running,
Completed
}

IWork

public interface IWork
{
WorkState State { get; set; }
void Perform();
}

关键类WorkQueue

public class WorkQueue
{
private List<IWork> _vlstWork = new List<IWork>();

public void Add(IWork work)
{
lock (this)
{
_vlstWork.Add(work);
}
}

public int GetCount(WorkState state)
{
lock (this)
{
int count = 0;
_vlstWork.ForEach(item =>
{
if (item.State == state)
count++;
});
return count;
}
}

public IWork GetWork()
{
lock(this)
{
foreach (IWork work in _vlstWork)
if (work.State == WorkState.Ready)
return work;
return null;
}
}
}

重点类ThreadScheduler

public delegate void AllFinishedHandler();
public class ThreadScheduler
{
private readonly int _viConcurrentLimit = 10;
private WorkQueue _vWorkQueue = null;

public AllFinishedHandler OnAllFinished = null;

public WorkQueue WorkQueue
{
get { return _vWorkQueue; }
}
public int ConcurrentLimit
{
get { return _viConcurrentLimit; }
}

public ThreadScheduler():this(new WorkQueue(),10) { }
public ThreadScheduler(WorkQueue workQueue):this(workQueue,10){ }
public ThreadScheduler(int concurrent) : this(new WorkQueue(),concurrent) { }
public ThreadScheduler(WorkQueue workQueue,int concurrent)
{
_vWorkQueue = workQueue;
_viConcurrentLimit = concurrent;
}

public void StartWork()
{
CheckAllFinished();

while (_vWorkQueue.GetCount(WorkState.Ready) > 0)
{
System.Diagnostics.Trace.WriteLine(_vWorkQueue.GetCount(WorkState.Ready));
if (_vWorkQueue.GetCount(WorkState.Running) < _viConcurrentLimit)
{
IWork work = _vWorkQueue.GetWork();
work.State = WorkState.Running;
if (work != null)
{
System.Threading.Thread thread = new System.Threading.Thread(() => {
work.Perform();
work.State = WorkState.Completed;
});
thread.IsBackground = true;
thread.Start();
}
}
}
}

   //这里要是用 一个volatile变量 来实现更准确的测试完成时间。不需要新起来一个线程啊!当然这个方法的调用位置需要修改。

private void CheckAllFinished()
{
System.Threading.Thread thread = new System.Threading.Thread(() => {
while (_vWorkQueue.GetCount(WorkState.Running) + _vWorkQueue.GetCount(WorkState.Ready) > 0)
{
System.Threading.Thread.Sleep(50);
}
if (OnAllFinished != null)
OnAllFinished();
});
thread.IsBackground = true;
thread.Start();
}

}

测试类TestWork

public class TestWork : IWork
{
private string _vsName = string.Empty;
private static int _viIndex = 1;
private WorkState _vState = WorkState.Ready;

public WorkState State
{
get { return _vState; }
set { _vState = value; }
}

public TestWork() { }
public TestWork(string name)
{
_vsName = name;
}

public void Perform()
{
Console.WriteLine("{0}.{1}--------Thread:{2}",_viIndex++,_vsName,System.Threading.Thread.CurrentThread.Name);
}
}

看看 效果:

class Program
{
static void Main(string[] args)
{
List<string> list = new List<string>();// new List<string>(new string[] { "Sunday", "Monday", "Tuesday", "Wednesday" });

#region Test One
/*
int count = 2;
System.Threading.Thread[] threadArray = new System.Threading.Thread[count];
for (int i = 0; i < count; i++)
{
threadArray[i] = new System.Threading.Thread(new TestWork(list[i]).Perform);
threadArray[i].Name = string.Format("WT#{0}", i);
threadArray[i].IsBackground = true;
}

foreach (System.Threading.Thread thread in threadArray)
{
thread.Start();
}
*/
#endregion

Random random=new Random();
for (int i = 0; i < 10000; i++)
{
list.Add(random.Next(10000).ToString());
}

DateTime startDateTime = DateTime.Now;
Console.WriteLine("There are {0} works as follows:", list.Count);
ThreadScheduler vThreadScheduler = new ThreadScheduler(8000);
list.ForEach(item=>{
vThreadScheduler.WorkQueue.Add(new TestWork(item));
});
vThreadScheduler.OnAllFinished += () =>
{
DateTime endDateTime=DateTime.Now;
Console.WriteLine("Works:{3},Used Time={0} <--- {1}-{2}",
endDateTime-startDateTime,endDateTime.ToString(),
startDateTime.ToString(),
vThreadScheduler.ConcurrentLimit
);
};
vThreadScheduler.StartWork();

Console.WriteLine("Over");
Console.Read();
}
}

测试发现当thread数量为任务数量一半的时候比80%要 快,比100%更快。当然这里的任务是小任务。

源码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: