【发布时间】:2020-06-07 07:54:24
【问题描述】:
您好最近对TPL Dataflow 产生了浓厚的兴趣,我想将它集成到我的ASP .NET Core 应用程序中。
我想将它用作管道,来自应用程序不同部分的多个方法可以将数据发布到这个 DataFlow 链。
我不知道的是,如果您希望从多个地方调用它们,您将块链接存储在哪里?
制片人
public class Producer
{
private BufferBlock<int> startBlock{get;}
private ActionBlock<int> ioBlock{get;}
private IOService service;
private void InitializeChain()
{
this.startBlock=new BufferBlock<int>();
var transformLink=new TransformBlock<int,string>([something]);
// some chain of blocks here
this.ioBlock=new ActionBlock<int>(async(x)=>await this.service.WriteAsync(x));
this.startBlock.LinkTo([someBlock]).LinkTo([someOtherBlock])......LinkTo(ioBlock);
}
public async Task AddAsync(int data)
{
this.BufferBlock.Post(data);
}
public Producer(IOService service)
{
this.service=service;
this.InitializeChain();
}
}
API 生产者
我设想这个 Producer 会从我的应用程序的多个部分调用,为了简洁起见,请使用 Controller-s:
public class C1:Controller
{
private Producer producer;
[HttpPost]
[Route([someroute])
public async Task SomeRoute(int data)
{
await this.producer.AddAsync(data);
}
[HttpGet]
[Route([someotherroute])
public async Task SomeOtherRoute(int data)
{
await this.producer.AddAsync(data);
}
public C1(Producer producer)
{
this.producer=producer;
}
}
启动
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton<Producer>();
}
这可以扩展到多个Controller 场景或更深的层次结构。
现在我的问题是:
保持Dataflow 链的Producer 应该如何注入?它应该是暂时的吗? Blocks 是否应该在每次调用时实例化?
不知道这个设计好不好。我知道 TPL Dataflow 是线程安全的,但是可以这样用吗?
P.S如果我希望它在我的ASP NET Core 应用程序的整个范围内可用,我基本上不知道以什么形式保留我的Dataflow 管道及其生命周期。
我想从多个端点(直接或更深地调用层次结构)获取数据,对它们进行批处理,转换它们,并控制它们最终写入外部源的方式(async 操作)。
这与现有的ThreadPool 或ASP NET Core 配合得好吗?
P.S 2:这个问题也困扰着我,因为Rx 等价物。
【问题讨论】:
-
这个管道是打算在每个 Web 请求上创建,还是打算在应用程序方面,并在应用程序的整个生命周期内持久保存在内存中?在第二种情况下,我建议看看这个:Fire and Forget on ASP.NET。 TL;DR 您的管道可能会随着应用程序频繁且不确定地被回收。
-
我认为它适合第二种情况,因为我希望这个管道创建一次,然后在我的应用程序中的任何地方使用。我需要一个我的所有数据进入的地方(通过我的应用程序)得到转换,聚合然后分批写入其他地方(也许)。还有你说的回收是什么意思?如果我使用单例对象,它不会在所有应用程序生命周期中持续存在吗?
-
这取决于管道完成的工作类型。例如,如果它产生了一些不重要的统计数据,那么我想时不时丢失一些数据不会是什么大问题。
-
如果偶尔数据无法在底层存储介质中持久化会不会有问题?客户端是否能够稍后确认数据实际上已被持久化,如果不能再次尝试发送它们?