为什么我真的需要这个:(底部问题的简单描述,在edit3下)
让我们想象一下,我尝试为 twitter 创建应用程序。它有尽可能多的帐户,我现在或以后要添加(例如 10 个)。因此,对于每个帐户,我们都有一个选项:
- 来自 rss 的推文;
- 跟随人;
- 转发任何推文。
当我们谈论一个帐户时,每个任务都应该在后台工作并在其他任务中同步。对于其中一个帐户,一次(请求太多)不会有推特和关注。
好的,这意味着,我一次只能为每个帐户执行一项任务。这是否意味着,我必须为这个时刻帐户中的每个活动组织一个线程?但是线程是什么,告诉每个帐户下一步该做什么(填满队列)?一个账号想推特,另一个只是转发和关注人:
- (thread 1) Account A:整天想从RSS/文件推文;
- (线程2)账号B:想每30秒转发一次,每15分钟关注人一次;
- (线程 3):应该填满“帐户 A”的队列(制作 twite,制作 twite,制作 twite);
- (线程 4):应该填满“帐户 B”的队列(进行转发,进行转发(在 15 分钟内,每 30 秒)...关注人,进行转发...);
在这种情况下,当每个帐户的一个线程刚刚开始工作(队列中的内容->他做了什么)而另一个线程刚刚填满队列时,我可以在我的功能中添加手动任务(现在,我所有的账户,转发这个 twite或跟随这个人),-在每个队列中,我将添加一个新任务,然后每个线程尽快执行该任务。
所以,我的目标(目标)是创建一个应用程序,每个帐户都应该在其中工作,我可以选择告诉他们下一步该做什么(更改他们的任务优先级)。
我想问你,我对每个 acc 2 个线程,关于队列(也许它应该是一个全局队列,线程使用帐户作为标记(分隔符)来执行任务)是否正确,也许你可以建议我关于我的任务的一些事情。
编辑: 那里最大的问题是,如果我创建 20 个帐户,但只有 5 个线程(限制)- 所以它不应该是 1 个 acc-> 2 线程,应该是 1 个线程来填充队列(看起来像全球),以及其他用于制作工作 - 但他们可以为一个帐户制作作品(一个线程制作 twite,其他线程开始关注用户),这让我陷入困境, - 不明白,我应该如何组织所有这个线程。
Edit2:还有一个问题:执行时间。我是否应该检查每个线程时间,何时执行任务(计划下一个小时的任务)(现在 23:55,这个任务将在 23:59 执行,-下一步是什么?跳过?睡觉?)。
如果我不应该检查时间并且在队列中只添加任务,那已经准备好执行,我又遇到了一个帐户一个任务的问题(设置添加 twite 15 秒延迟,添加转发 20 秒延迟,跟随人们 60 秒延迟) => 每分钟我将有 3 个任务在队列中,但应该一个一个地执行(我有 100 个帐户,但只有 5 个工作线程(它们应该相互同步,什么帐户任务现在执行其他线程?)) .
Edit3(让它变得简单): 好吧,让我们忘记推特吧。我要编写 Windows 桌面应用程序,它应该在控制台中写一些东西(让它成为“来自 Bob 的你好”、“来自 Bob 的嗨”、“来自 Bob 的再见”)。
我可以在我的程序中添加很多名字(Bob、Jack、John、Dave、Scott)并检查这些名字应该写什么短语:
- Bob 每 15 秒只写一次“来自 Bob 的你好”;
- 杰克每 1 分钟写一次“来自杰克的你好”,每 5 秒写一次“来自杰克的再见”;
- John 写 'hello', 'hi', 'bye' + from 'John', 5 seconds, 10 seconds, 15 seconds;
- 等(假设为 20 个名称);
我希望,这样好吗?
所以,现在,当我启动我的应用程序时,这 20 个名字中的每一个都应该在控制台中写下他们的短语,但是要在他们的时间和所有线程中进行(让限制它有 10 个工作线程) - 应该是每个名字一个任务(如果一个线程现在写 'hello from Jack',其他线程不应该写 'bye from Jack',即使这个任务应该在 01:42:00 执行。只有当 Jack 完成一项任务时,其他任务才开始) .
(+) 另外,我应该有一个选项,在他们最接近的任务完成后,为这个名字中的某个人添加我想要的任何短语。
我希望,我会找到你的帮助。
编辑4:所以:
谢谢帮助,现在我知道我需要什么以及如何组织我的应用程序。
最终实现:
我已经使用自己的代码完成了我的任务,对我来说,解决方案看起来是最好的。
因此,当我为每个帐户生成队列并将它们放入一个全局应用程序任务队列时,我将其传递给 TimerCallBack 函数,该函数检查队列中是否有任何准备好执行的任务(但仅检查 event_elements[0] ),- 如果是这样,设置 isactive = true (对于个人队列,防止执行下一个事件,在前一个完成之前),并放置这个队列,应该在迭代后执行每个第一个事件。
然后,将其作为集合传递给 Parallel.ForEach:
Parallel.ForEach(readyToExec, new ParallelOptions { MaxDegreeOfParallelism = 5 }, eq =>
{
lock (eq)
{
QueueElement exec_elem = eq.elements[0];
Console.WriteLine(exec_elem.timeToExecute + ": " + eq.account.Name + " " + exec_elem.EventType);
exec_elem.timeToExecute = DateTime.Now + exec_elem.timeDelay;
eq.timeLastExecute = DateTime.Now;
eq.elements.Sort();
eq.isactive = false;
}
});
顺便说一句,在添加要执行的事件之前添加了检查:
foreach (var equeue in queue)
{
if (!equeue.isactive && equeue.elements[0].readyToExecute)
{
if (DateTime.Now > equeue.timeLastExecute + TimeSpan.FromSeconds(5))
{
equeue.isactive = true;
readyToExec.Add(equeue);
}
else
{
equeue.elements[0].timeToExecute = DateTime.Now + TimeSpan.FromSeconds(5);
}
}
}
以手动延迟执行一个帐户的事件(例如,如果在 00:00:00 写入“Hello”,则直到 00:00:05 才能开始执行下一个事件,即使此执行时间为 00 :00:02)。
所以,它对我很有用;)