gpt4 book ai didi

c# - 如何在C#中正确地排队和执行具有可变开始时间的任务?

转载 作者:行者123 更新时间:2023-12-03 13:21:29 27 4
gpt4 key购买 nike

我还是C#的新手。当前使用.NET 3.5。我正在写一个在线游戏,我的游戏引擎需要处理玩家要求的单位移动。单元将以不同的速度移动并且可能具有不同的目的地,因此单元到达(和命令完成)的实际时间将有很大差异。

我的策略是该模型将计算沿给定路径的下一个移动,然后将 worker 排队等待大约在装置到达该位置的同一时间执行。工作人员将更新单位,通知玩家,排队下一步,等等。

我最大的绊脚石之一是编写一个可以有条件地执行任务的工作线程。过去,我的工作线程只是试图尽快运行每个任务。另一个挑战是,单元移动的开始时间可能比队列中任何其他任务的开始时间都要早,所以很明显,他们需要移至生产线的最前面。

到目前为止,这是我已经弄清楚的,它可以运行,但是有一些限制,即其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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com