WCF 任务调度程序,或 OGame、Travian 等中的计时器
我正在寻找资源,或者任何在 WCF 中编写调度程序的人。 我想要实现的基本上是您在 OGame、Travian 或许多其他基于文本浏览器的游戏中看到的内容。
玩家点击并将任务发送到服务器来为他、单位或其他东西建造建筑。 据我所知,我需要在服务器上运行某种调度程序来收集所有任务并跟踪它们,直到经过一段时间(2分钟、10分钟、3天等),并在该时间段之后最终服务应该调用一个操作,例如将数据发送到数据库。
出色地。我一直在尝试做一些非常简单的事情,我可以以此开始和结束:
public class BuildingScheduler
{
public int TaskID { get; set; }
public string UserName { get; set; }
public DateTime TaskEnd { get; set; }
public string BuildingName { get; set; }
public bool TaskDone { get; set; }
public DateTime RemainingTime { get; set; }
TestDBModelContainer _ctx;
TestData _testData;
public IDuplexClient Client { get; set; }
public BuildingScheduler()
{
TaskDone = false;
}
public void MakeBuilding()
{
while (DateTime.Now <= TaskEnd)
{
//Client.DisplayMessage(DateTime.Now.ToString());
RemainingTime = DateTime.Now;
}
_testData = new TestData { DataName = BuildingName, Created = DateTime.Now };
_ctx = new TestDBModelContainer();
_ctx.TestDataSet.AddObject(_testData);
_ctx.SaveChanges();
TaskDone = true;
//Client.DisplayMessage("Building completed!");
}
}
static List<UserChannel> _userChannels = new List<UserChannel>();
static List<BuildingScheduler> _buildingSchedules = new List<BuildingScheduler>();
List<BuildingScheduler> _buildingSchedulesToRemove = new List<BuildingScheduler>();
[OperationContract]
public void DoWork()
{
IDuplexClient client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
UserChannel userChannel = new UserChannel { Client = client, ClientName = "TestClient" };
string clientName = (from p in _userChannels
where p.ClientName == "TestClient"
select p.ClientName).FirstOrDefault();
lock (((ICollection)_userChannels).SyncRoot)
{
if (clientName == null)
{
_userChannels.Add(userChannel);
}
}
CheckBuilding();
}
private void CheckBuilding()
{
BuildingScheduler bs = (from p in _buildingSchedules
where p.UserName == "TestClient"
select p).FirstOrDefault();
IDuplexClient client = (from p in _userChannels
where p.ClientName == "TestClient"
select p.Client).FirstOrDefault();
if (bs != null)
{
client.DisplayMessage(bs.RemainingTime);
}
}
private void StartBuilding()
{
foreach (BuildingScheduler bs in _buildingSchedules)
{
if (bs.TaskDone == false)
{
bs.MakeBuilding();
}
else if (bs.TaskDone == true)
{
_buildingSchedulesToRemove.Add(bs);
}
}
for(int i = 0; i <= _buildingSchedulesToRemove.Count; i++)
{
BuildingScheduler bs = _buildingSchedulesToRemove.Where(p => p.TaskDone == true).Select(x => x).FirstOrDefault();
_buildingSchedules.Remove(bs);
_buildingSchedulesToRemove.Remove(bs);
}
CheckBuilding();
}
[OperationContract]
public void MakeBuilding(string name)
{
BuildingScheduler _buildng = new BuildingScheduler();
//_buildng.Client = client;
_buildng.TaskID = 1;
_buildng.UserName = "TestClient";
_buildng.TaskEnd = DateTime.Now.AddSeconds(50);
_buildng.BuildingName = name;
_buildingSchedules.Add(_buildng);
StartBuilding();
}
我已经对大多数值进行了硬编码,以进行测试。
InstanceContextMode 是为 PerCall 设置的。
反正。这段代码正在运行。至少在某种程度上。如果我们忽略实体框架中的 zylion 异常,我可以添加来自多个客户端的任务,并将它们按照从新集到最旧集(或从最短到最长?)的顺序添加到数据库中。
关键是,用户无法跟踪他的任务。当我更改页面时,我看不到任务完成还剩多少时间。该代码本质上不提供时间跟踪,因为我摆脱了它,因为它无论如何都不起作用。
我想我应该将我的任务存储在一些预先存在的数据存储中,并且每次用户检查页面新闻集状态都应该从该存储中提取并发送给他。
我不是专家,但我认为最好的选择是将所有数据存储在内存中,直到任务完成。 如果我必须不断用新的任务状态更新记录,任何关系数据库都可能会变慢。
我知道我应该只将客户端计时器与服务器同步,而不是从服务器持续传输时间。但最大的问题是,当用户 3 秒或 3 小时后返回页面时,如何获取任务进度的新集状态?
有关如何使其按预期工作的任何建议。
顺便说一句。我正在使用 pollingduplex 和 Silverlight。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
听起来您正在使用 WCF 来做一些其设计目的之外的事情(但我理解其需要)。我建议您将 Workflow Foundation (WF) 作为您问题的可能解决方案。这是一个很好的解释:
http://msdn.microsoft.com/library/dd851337.aspx
这也是一个很好的介绍视频:
http://channel9.msdn.com /Blogs/mwink/Introduction-to-Workflow-Services-building-WCF-Services-with-WF
工作流可以使用 WCF 服务,并且它被设计为随着时间的推移而工作。它将数据保存在状态中,直到发生变化(无论时间长短),而不会消耗过多的资源。此外,它还允许持久性和并行进程。
It sounds like you are using WCF to do something for which it wasn't designed (but I understand the need). I would suggest you look at Workflow Foundation (WF) as a possible solution to your problem. Here is a good explanation:
http://msdn.microsoft.com/library/dd851337.aspx
Here is also a good intro video:
http://channel9.msdn.com/Blogs/mwink/Introduction-to-Workflow-Services-building-WCF-Services-with-WF
Workflow can consume WCF services and it is designed to work over time. It holds data in state until something changes (regardless of time) without consuming excess resources. Also, it allows for persistance and parallel processes.