我还是 C# 新手。目前使用.NET 3.5。我正在编写一个在线游戏,我的游戏引擎需要处理玩家请求的单位移动。这些单位将以不同的速度移动,并且可以有不同的目的地,因此单位到达(以及命令完成)的实际时间会有很大差异。
我的策略是,模型将计算沿着给定路径的下一步移动,然后将工作人员排队以在单位到达该位置的同时执行。工作人员将更新单元、通知玩家、排队下一步等。
我最大的障碍之一是编写一个有条件执行任务的工作线程。过去,我的工作线程只是尝试尽快按顺序运行每个任务。另一个挑战是,单元移动可能会比队列中的任何其他任务具有更早的开始时间,因此显然,它们需要移动到队列的前面。
这是我到目前为止所想出的,它有效,但有一些限制,即它的 100 毫秒 sleep 限制了我的命令响应时间。我想要做的事情是否有一个模式,或者我是否遗漏了一些明显的东西?
谢谢!
public class ScheduledTaskWorker
{
List<ScheduledTask> Tasks = new List<ScheduledTask>();
public void AddTask(ScheduledTask task)
{
lock (Tasks)
{
Tasks.Add(task);
Tasks.Sort();
}
}
private void RemoveTask(ScheduledTask task)
{
lock (Tasks)
{
Tasks.Remove(task);
}
}
private ScheduledTask[] CopyTasks()
{
lock (Tasks)
{
return Tasks.ToArray();
}
}
public void DoWork()
{
while (!StopWorking)
{
ScheduledTask[] safeCopy = CopyTasks();
foreach (ScheduledTask task in safeCopy)
{
if (task.ExecutionTime > DateTime.Now)
break;
if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCallBack), task))
RemoveTask(task);
else
{
// if work item couldn't be queued, stop queuing and sleep for a bit
break;
}
}
// sleep for 100 msec so we don't hog the CPU.
System.Threading.Thread.Sleep(100);
}
}
static void ThreadPoolCallBack(Object stateInfo)
{
ScheduledTask task = stateInfo as ScheduledTask;
task.Execute();
}
public void RequestStop()
{
StopWorking = true;
}
private volatile bool StopWorking;
}
还有任务本身...
public class ScheduledTask : IComparable
{
Action<Item> Work;
public DateTime ExecutionTime;
Item TheItem;
public ScheduledTask(Item item, Action<Item> work, DateTime executionTime)
{
Work = work;
TheItem = item;
ExecutionTime = executionTime;
}
public void Execute()
{
Work(TheItem);
}
public int CompareTo(object obj)
{
ScheduledTask p2 = obj as ScheduledTask;
return ExecutionTime.CompareTo(p2.ExecutionTime);
}
public override bool Equals(object obj)
{
ScheduledTask p2 = obj as ScheduledTask;
return ExecutionTime.Equals(p2.ExecutionTime);
}
public override int GetHashCode()
{
return ExecutionTime.GetHashCode();
}
}
最佳答案
我并不反对克里斯的观点,他的回答可能更适合您的根本问题。
但是,要回答您的具体问题,您可以使用类似于 Java 的 DelayQueue 的内容。 ,它看起来已在此处移植到 C#:http://code.google.com/p/netconcurrent/source/browse/trunk/src/Spring/Spring.Threading/Threading/Collections/Generic/DelayQueue.cs?spec=svn16&r=16
您的Task
类将实现 IDelayed
那么您可以有一个线程调用 Take(在没有准备好项目时会阻塞)并执行任务,或者将它们传递给 ThreadPool.QueueUserWorkItem
.
关于c# - 如何在 C# 中正确排队和执行具有可变开始时间的任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7629849/