c# – TPL数据流循环完成
我在确定如何在循环TPL数据流中检测完成时遇到问题.
我在数据流的一部分中有一个反馈循环,它向远程服务器发出GET请求并处理数据响应(用更多数据流转换这些数据流然后提交结果). 数据源将其结果拆分为1000条记录的页面,并不会告诉我它有多少页面可供我使用.我必须继续阅读,直到我得到不到一整页的数据. 通常页数是1,经常是10,每次我们都有1000. 我有很多要求在开始时提取. 我遇到的问题是当我将此逻辑放入数据流时,例如: //generate initial requests for activity var request = new TransformManyBlock<int,DataRequest>(cmp => QueueRequests(cmp)); //fetch the initial requests and feedback more requests to our input buffer if we need to TransformBlock<DataRequest,DataResponse> fetch = null; fetch = new TransformBlock<DataRequest,DataResponse>(async req => { var resp = await Fetch(req); if (resp.Results.Count == 1000) await fetch.SendAsync(QueueAnotherRequest(req)); return resp; },new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 }); //commit each type of request var commit = new ActionBlock<DataResponse>(async resp => await Commit(resp)); request.LinkTo(fetch); fetch.LinkTo(commit); //when are we complete? QueueRequests产生IEnumerable< DataRequest>.我立刻将下一个N页请求排队,接受这意味着我发送的呼叫数量比我需要的多一些. DataRequest实例共享一个LastPage计数器,以避免无意中发出我们知道在最后一页之后的请求.这一切都很好. 问题: 我可以在fetch上监视输入和输出缓冲区是否为空,但我认为当我设置完成时,我仍然冒着获取仍然忙于请求的风险,因此阻止了对其他页面的排队请求. 我可以通过某种方式知道提取繁忙(输入或忙于处理输入). 我错过了解决这个问题的明显/直接的方法吗? >我可以在fetch中循环,而不是排队更多的请求.问题是我希望能够使用设置的最大线程数来限制我正在对远程服务器做的事情.块内的并行循环是否可以与块本身共享调度程序,并通过调度程序控制生成的线程数? 非常感谢您提供的任何帮助! 解决方法
在TPL Dataflow中,您可以使用
DataflowLinkOptions
link the blocks指定
propagation of completion of the block:
request.LinkTo(fetch,new DataflowLinkOptions { PropagateCompletion = true }); fetch.LinkTo(commit,new DataflowLinkOptions { PropagateCompletion = true }); 之后,您只需为请求块调用 // the completion will be propagated to all the blocks request.Complete(); 你应该使用的最后一件事是最后一个块的 commit.Completion.ContinueWith(t => { /* check the status of the task and correctness of the requests handling */ }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |