使用带有参数作为函数参数的C#异步任务

问题描述 投票:0回答:1

我正在构建自己的基于队列的系统,但到目前为止,我有一个小问题:如何将异步任务添加到另一个函数中以对其进行处理?

我的处理器功能如下:

  • 我有一个队列对象:

    public class Queue
    {
     public string Id;
    
     public CancellationTokenSource Cts;
    
     public Task Task;
    
     public Queue(Task task, string id, CancellationTokenSource cts)
     {
        Id = id;
        Cts = cts;
        Task = task;
     }}
    

以及将我的任务添加到2个列表的命令:List<Queue> ActiveQueuesList<Queue> Queued

[ActiveQueues是具有所有活动队列的列表,而Queued是具有所有队列的列表。

我的添加功能看起来像这样:

public async Task Add(Task task, string id, CancellationTokenSource cts)
{
    var queue = new Queue(task, id, cts);
    if (ActiveQueues.Count < MainWindow.appConfig.MaxAsyncSessions)
    {
        var exists = ActiveQueues.Find(q => q.Id == queue.Id);
        if (exists == null) // I don't want 2 queues with the same id to run at once so I add it to the queued list that's processed by another function.
        {
            ActiveQueues.Add(queue);
            ActiveQueueIds.Add(queue.Id);
            await queue.Task;
        }
        else
        {
            Queued.Add(queue);
        }
    }
    else
    {
            Queued.Add(queue);
    }
}

问题是我的任务也有参数,因此像queue.Add(AsyncFunction(param1, param2), "idExample", new CancellationTokenSource())一样使用它会在将函数添加到ActiveQueues列表之前触发该函数。

现在要做我想做的正确方法是什么?

c# task-parallel-library
1个回答
1
投票

更改您的Add方法签名以接受委托:

public async Task Add(Func<Task> taskFactory, string id, CancellationTokenSource cts)

然后相应地更改Queue ctor并引入类似Start的方法,该方法将启动任务(基本调用taskFactory()),并可选地进行验证(如果已启动)并缓存taskFactory()的结果,或将Lasy<>用于处理它。

使用Lasy<>的简单实现可能看起来像这样(为简洁起见,省略了一些代码):

Lazy
© www.soinside.com 2019 - 2024. All rights reserved.