通过我的WCF
服务,我正在解决一个兼具性能和设计效果的问题。
该服务是一种无状态RESTful
PerCall
服务,可以完成许多简单而常见的服务,这些服务都像花花公子一样。
但是,有一个操作,最近已经开始吓到我了,所以有问题:
客户端对操作进行参数化调用,结果的计算需要大量时间才能完成。但是,具有相同参数的调用的结果将始终相同,直到服务器上的数据发生更改。并且客户使用完全相同的参数进行糟糕的LOT 调用。但是,服务器无法预测用户会喜欢的参数,所以遗憾的是,结果无法预先计算。
所以我提出了缓存层并将结果对象存储为键值对,其中key表示导致此结果的参数。如果相关数据发生变化,我只需刷新缓存即可。仍然很简单,没有问题。
客户端调用服务,服务器接收调用,查看结果是否已缓存并返回,如果是,则返回。但是,如果结果尚未缓存,则客户端启动计算。计算可能需要2分钟(平均时间10-15秒)才能完成,到那时,其他客户端可能会来,并且因为结果仍然不知道缓存,它们中的每一个都会开始自己的计算。这是 NOT 我们真正想要的东西,所以有一个标志,如果有人已经用这个参数开始计算,这就是代码中的位置,其他调用者的代码停止并等待计算到完成并插入到缓存中,每个被调用的实例将从中获取结果,将其返回给客户端并进行处置。 这是我真正在努力的部分。
到目前为止,我的解决方案看起来像这样(在你进一步阅读之前,我想警告你,因为我的经验并不接近体面,我仍然是所有C#
中的大菜鸟,{{1和相关的东西......不需要告诉我,我是一个菜鸟,因为我完全清楚这一点):
WCF
如您所见,此解决方案存在更多问题:
所以,就像大部分时间一样,我做了我的作业并在询问前进行了qoogling,但没有成功找到一些我理解或适合我的问题和领域的指导。
我有一种强烈的感觉,我必须介绍某种(静态?)基于事件的事件和异步类(如果你愿意,可以调用它),它会做一些技巧并组织和管理所有这些在某种程度上注册到我和我将给你一个戳/戳 - 所有注册线程的方式。但是尽管能够(在某种程度上)使用新引入的任务Stopwatch sw = new Stopwatch();
sw.Start();
while (true)
{
if (Cache.Contains(parameters) || sw.Elapsed > threshold)
break;
Thread.Sleep(100);
}
...do relevant stuff here
和async-await,我不仅在这个领域的经验非常有限,更遗憾的是,我真的需要帮助来解释它如何能够与事件一起(或者我甚至需要它们?)...当我在测试控制台应用程序中尝试/运行小东西时,我可能会成功,但将它带入我TPL
应用程序的更大环境中,我很难找到线索。
所以,我很乐意欢迎各种相关的想法,建议,指导,链接,代码和批评来触及我的主题。
我知道这个事实,它可能会令人困惑,并会尽力清除所有误解和棘手的部分,只要求我这样做。
感谢您的帮助!