c# - TPL FromAsync 与 TaskScheduler 和 TaskFactory

标签 c# .net parallel-processing task-parallel-library

我正在尝试结合使用 TaskFactory.FromAsync 创建任务管道/有序调度程序.

我希望能够触发 Web 服务请求(使用 FromAsync 来使用 I/O 完成端口)但保持它们的顺序并且在任何时候只执行一个请求。

目前我不使用FromAsync所以我可以做TaskFactory.StartNew(()=>api.DoSyncWebServiceCall())并依赖 OrderedTaskSchedulerTaskFactory 使用以确保只有一个请求未完成。

我假设在使用 FromAsync 时这种行为会持续存在方法,但它没有:

TaskFactory<Stuff> taskFactory = new TaskFactory<Stuff>(new OrderedTaskScheduler());
var t1 = taskFactory.FromAsync((a, s) => api.beginGetStuff(a, s), a => api.endGetStuff(a));
var t2 = taskFactory.FromAsync((a, s) => api.beginGetStuff(a, s), a => api.endGetStuff(a));
var t3 = taskFactory.FromAsync((a, s) => api.beginGetStuff(a, s), a => api.endGetStuff(a));

所有这些 beginGetStuffFromAsync 中调用方法调用(所以尽管它们是按顺序发送的,但同时有 n api 调用)。

FromAsync 过载需要一个 TaskScheduler:

public Task FromAsync(
    IAsyncResult asyncResult,
    Action<IAsyncResult> endMethod,
    TaskCreationOptions creationOptions,
    TaskScheduler scheduler
)

但是文档说:

The TaskScheduler that is used to schedule the task that executes the end method.

如您所见,它需要已经构建好的 IAsyncResult , 不是 Func<IAsyncResult> .

这是否需要自定义 FromAsync方法还是我遗漏了什么?谁能建议从哪里开始实现?

干杯,

编辑:

我想从调用者那里抽象出这种行为,按照 TaskFactory 的行为(使用专门的 TaskScheduler ),我需要立即返回任务 - 此任务不仅会封装 FromAsync任务以及该任务在等待轮到执行时排队。

一种可能的解决方案:

class TaskExecutionQueue
{
    private readonly OrderedTaskScheduler _orderedTaskScheduler;
    private readonly TaskFactory _taskFactory;
    public TaskExecutionQueue(OrderedTaskScheduler orderedTaskScheduler)
    {
        _orderedTaskScheduler = orderedTaskScheduler;
        _taskFactory = new TaskFactory(orderedTaskScheduler);

    }

    public Task<TResult> QueueTask<TResult>(Func<Task<TResult>> taskGenerator)
    {
        return _taskFactory.StartNew(taskGenerator).Unwrap();
    }
}

然而,这在 FromAsync 时使用了一个线程调用正在发生。理想情况下,我不必那样做。

最佳答案

您无法安排 IO 任务,因为它们没有关联的线程。 Windows 内核提供无线程 IO 操作。启动这些 IO 不涉及托管代码,TaskScheduler 类不会发挥作用。

因此,您必须延迟启动 IO,直到您确定确实希望网络受到攻击。您可以使用 SemaphoreSlim.WaitAsync 来限制当前运行的任务数量。在启动单个 IO 之前等待该方法的结果并等待它。

关于c# - TPL FromAsync 与 TaskScheduler 和 TaskFactory,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13746421/

相关文章:

c# readonly DataGridView 与一个启用的单元格

c# - 所查看的 MSMQ 消息的 message.ID 不知何故丢失

parallel-processing - 弗林克 : how does the parallelism set in the Jobmanager UI relate to task slots?

python - 使用多处理池的 apply_async 方法时谁运行回调?

c# - 在 JSON.NET 中修剪 json 字符串

algorithm - 如何将此类 DFS 算法问题扩展/分布到分布式系统中

c# - Windows 服务以用户身份连接到 Azure AD (MFA)

c# - 如何在 C# 中获取所有 Windows 事件日志(事件查看器日志)及其层次结构和友好名称的列表

C# MySQL Re-Usable 类安全问题

.net - 测量 WPF 渲染的性能