我有一个Windows服务(使用Topshelf
),它托管WCF
服务(使用SimpleInjectorServiceHost
创建)并且还旋转线程(使用Task.Run
)。
这个想法是:
WCF
服务接收命令BufferBlock<T>
。该服务需要将BufferBlock<T>
注入其构造函数TransformBlock<T>
,它将执行必要的操作并返回结果WCF
服务方法回读并返回给调用者我刚开始使用TPL Dataflow,所以也许我对动作块的理解是完全错误的
我在Windows服务OnStart方法中旋转线程
for(var i = 0, i < Environment.ProcessorCount, ++i)
{
Task.Run(() =>
{
using (var scope = Bootstrapper.BeginScope())
{
var threadHost = Bootstrapper.GetInstance<IThreadHost>();
threadHost.DoWork(_cancellationTokenSource.Token);
}
}, _cancellationTokenSource.Token);
};
Bootstrapper.BeginScope
简单地抽象出SimpleInjector的_container.BeginLifetimeScope()
方法
IThreadHost
/ ThreadHost
是一个简单的接口/类,它包含每种命令类型的方法。 DoWork
应该等待BufferBlock
并处理每个项目一次。
使用
启动WCF
服务
if (_serviceHost != null)
{
_serviceHost.Close();
}
_serviceHost = Bootstrapper.CreateServiceHost(typeof(NodeService));
_serviceHost.Open();
Bootstrapper.CreateServiceHost
只是抽象出new SimpleInjectorServiceHost(_container, serviceType)
。
问:BufferBlock<T>
是否应该是SimpleInjector
注册的单身人士?
问:如何将每个DoWork
的{{1}}设置为threadHost
并链接到TransformBlock<T>
?
问:如何在BufferBlock<T>
服务方法中获得TransformBlock<T>
的输出? WCF
服务方法将命令写入WCF
,然后需要以某种方式等待输出?
答案 0 :(得分:2)
我觉得你有点过于复杂了。您真的不需要TransformBlock
工作者的线程 - TPL DataFlow中的每个块都已经有相应的任务。如果您愿意,可以optimize it's usage for your needs with options。
您在解决方案中获得的是一般Producer/Consumer
pattern,使用TPL DataFlow可以更轻松地完成。所以你的第一个问题的答案是:
问:BufferBlock应该是在SimpleInjector注册的单身人士吗?
是的,BufferBlock
和TransformBlock
应该是单身,但这取决于第三个问题的答案
正如我已经说过的那样,你真的不需要TPL
和TPL DataFlow
的帖子,所以第二个问题也很容易回答:
问:如何将每个threadHost的DoWork设置为TransformBlock和链接 到BufferBlock?
您应该在解决方案中不使用任何主题,并直接将TransformBlock
链接到BufferBlock
至于第三个问题,这是有趣的部分,因为答案是:
问:如何在WCF服务方法中获得TransformBlock的输出? WCF服务方法将命令写入BufferBlock然后需要 以某种方式等待输出?
取决于。
使用TPL DataFlow进行数据处理的主要思想是它是异步的,你无法确定退出TransformBlock
时所拥有的是你的请求的结果 - 可能是使用其他请求转换的其他数据,只需使用OutputAvailableAsync()
轮询输出,对于您的解决方案来说可能效率很低。
在这种情况下,您应该创建某种字典来处理结果,这样您就可以轻松获取信息,是否完成了请求。在这种实现的情况下,您可以返回请求的id,并引入另一种服务方法来获取该id的结果。
另一种方法是将数据流封装到一个帮助程序类中,该辅助程序类将包含它自己的BufferBlock
和TransformBlock
副本,在这种情况下,您可以创建async
使用轮询的方法,如链接示例中所示。请注意,在这种实施情况下,您根本不需要TPL DataFlow。