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

Use C# async task with arguments as a function parameter

我正在构建自己的基于队列的系统,但到目前为止我遇到了一个小问题:如何将异步任务添加到另一个函数来处理它?

我的处理器函数是这样工作的:

以及将我的任务添加到 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 列表之前触发函数。

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

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

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

并相应地更改 Queue ctor 并引入类似 Start 的方法,它将启动任务(基本上调用 taskFactory())并可选择验证它是否已经启动并缓存结果taskFactory() 或使用 Lasy<> 来处理它。

使用 Lazy 的简单实现如下所示(为简洁起见省略了一些代码):

class Queue
{
    public Lazy<Task> Task;
    public Queue(Func<Task> taskFactory)
    {
        Task = new Lazy<Task>(taskFactory);
    }
}

// in your Add method:    
var queue = new Queue(taskFactory);
await queue.Task.Value;

// Add call:
q.Add(() => AsyncFunction(param1, param2), "idExample", new CancellationTokenSource())