【发布时间】:2020-01-05 05:24:27
【问题描述】:
我开发了许多算法,它们使用常规的Threads 自行完成大部分线程。方法总是如下
float[] GetData(int requestedItemIndex)
通过上述方法,索引被推入一些消息队列,由个别算法的线程处理。所以最终算法的界面是这样的:
public abstract class AlgorithmBase
{
private readonly AlgorithmBase Parent;
private void RequestQueue()
{
}
public float[] GetData(int requestedItemIndex) => Parent.GetData(requestedItemIndex);
}
这个例子非常原始,但只是为了获得线索。问题是我可以链接当前适用于我的解决方案的算法。如您所见,每个 GetData 都会调用父算法的另一个 GetData。这当然会变得更复杂,当然需要有一个最终父级作为数据源,否则我会得到 StackOverflowExceptions。
现在我尝试通过使用 async/await 来改变这种行为。我的问题是,如果我重写我的代码,我会得到这样的结果:
public abstract class AlgorithmBase
{
private readonly AlgorithmBase Parent;
public async Task<float[]> GetDataAsync(int requestedItemIndex, CancellationToken token = default)
{
var data = await Parent.GetDataAsync(requestedItemIndex);
return await Task.Run<float[]>(async () => ProcessData());
}
}
现在,我已经链接了算法,每个新算法都跨越另一个任务,如果多次执行,这可能会非常耗时。
所以我的问题是,是否有一种方法可以通过使用定义接口将下一个任务嵌入到已经运行的任务中?
【问题讨论】:
-
问题在于任务,任务调度程序可能比您在 cpu 绑定和 io 绑定的工作负载中更好地管理它们。我不确定问题到底出在哪里。如果您想管道数据和工作流,最好查看 DataFlow 或 RX
-
@TheGeneral:我查看了这两个解决方案(DataFlow 和 Rx)。我的问题是我的所有需求都是基于拉的而不是基于推的。
-
@GSerg:感谢您的评论。老实说,我没有测试代码,我只是插入它以进行解释。
-
@GSerg 假设
ProcessData是同步方法,示例代码会产生警告(因为有一个async没有await),但是会等待方法的结果正好。 Task.Run() 理解异步委托。 -
@TheodorZoulias 出于某种原因,它在我脑海中闪过stackoverflow.com/q/24777253/11683。
标签: c# async-await task-parallel-library